From 0548bee8ad26d219a7b2f31216694b9bd506abb1 Mon Sep 17 00:00:00 2001 From: eeintech Date: Mon, 7 Sep 2020 11:29:24 -0500 Subject: [PATCH 1/7] Added Color Theme view in settings --- InvenTree/InvenTree/forms.py | 13 +- .../InvenTree/static/css/inventree-darker.css | 785 ++++++++++++++++++ InvenTree/InvenTree/urls.py | 3 +- InvenTree/InvenTree/views.py | 15 +- InvenTree/common/migrations/0007_theme.py | 20 + InvenTree/common/models.py | 14 + .../templates/InvenTree/settings/tabs.html | 3 + .../templates/InvenTree/settings/theme.html | 27 + 8 files changed, 875 insertions(+), 5 deletions(-) create mode 100644 InvenTree/InvenTree/static/css/inventree-darker.css create mode 100644 InvenTree/common/migrations/0007_theme.py create mode 100644 InvenTree/templates/InvenTree/settings/theme.html diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index 1e70b525c6..e090ab9de3 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -11,7 +11,7 @@ from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout, Field from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText from django.contrib.auth.models import User - +from common.models import Theme class HelperForm(forms.ModelForm): """ Provides simple integration of crispy_forms extension. """ @@ -161,3 +161,14 @@ class SetPasswordForm(HelperForm): 'enter_password', 'confirm_password' ] + + +class ThemeSelectForm(forms.ModelForm): + """ Form for setting color theme + """ + + class Meta: + model = Theme + fields = [ + 'theme' + ] \ No newline at end of file diff --git a/InvenTree/InvenTree/static/css/inventree-darker.css b/InvenTree/InvenTree/static/css/inventree-darker.css new file mode 100644 index 0000000000..2df593b2fa --- /dev/null +++ b/InvenTree/InvenTree/static/css/inventree-darker.css @@ -0,0 +1,785 @@ +:root { + --primary-color: #335d88; + --secondary-color: #b69c80; + --highlight-color: #f5efe8; + --basic-color: #333; + + --label-red: #e35a57; + --label-blue: #4194bd; + --label-green: #50aa51; + --label-grey: #aaa; + --label-yellow: #fdc82a; +} + +.markdownx .row { + margin: 5px; + padding: 5px; + border: 1px solid #cce; + border-radius: 4px; +} + +.markdownx-editor { + width: 100%; + border: 1px solid #cce; + border-radius: 3px; + padding: 10px; +} + +.panel-content { + padding: 10px; +} + +.markdownx-preview { + border: 1px solid #cce; + border-radius: 3px; + padding: 10px; +} + +/* Progress bars */ + +.progress { + position: relative; + width: 100%; + margin-bottom: 0px; + background: #eeeef5; +} + +.progress-bar { + opacity: 60%; + background: #2aa02a; +} + +.progress-bar-under { + background: #eeaa33; +} + +.progress-bar-over { + background: #337ab7; +} + +.progress-value { + width: 100%; + color: #333; + position: absolute; + text-align: center; + top: 0px; + left: 0px; + font-size: 110%; +} + +.qr-code { + max-width: 400px; + max-height: 400px; + align-content: center; +} + +.qr-container { + width: 100%; + align-content: center; +} + +.navbar-brand { + float: left; +} + +.navbar-barcode-li { + border-left: none; + border-right: none; +} + +.navbar-nav > li { + border-left: 1px solid; + border-right: 1px solid; + border-color: rgb(179, 179, 179); + +} + +.navbar-nav > li > a { + color:#0b2a62 !important; +} + +.navbar-nav > li > a:hover { + color:#202020 !important; +} + +.navbar-nav > .open > a { + color:#202020 !important; +} + + + + +.navbar-form { + padding-right: 3px; +} + +.navbar { + background-color: rgb(189, 189, 189); +} + +.table-condensed > tbody > tr > td { + border-top: 1px solid #062152 !important ; +} + +.table-striped > tbody > tr > td { + border-top: 1px solid #92b3f1 ; +} + +.table-bordered, .table-bordered > tbody > tr > td { + border: 1px solid rgb(182,182,182); +} + +.table-bordered > thead > tr > th { + border: 1px solid rgb(182, 182, 182); + background-color: rgb(235, 235, 235); +} + +h3 { + color:#06255d; +} + +#barcode-scan { + margin-top: 8px; +} + +.icon-header { + margin-right: 10px; +} + +.glyphicon { + font-size: 18px; +} + + +.glyphicon-small { + font-size: 12px; +} + +.glyphicon-right { + float: right; +} + +.starred-part { + color: #ffbb00; +} + +.red-cell { + background-color: #ec7f7f; +} + +.part-price { + color: rgb(13, 245, 25); +} + +.icon-red { + color: #c55; +} + +.icon-green { + color: #43bb43; +} + +.icon-blue { + color: #55c; +} + +.icon-yellow { + color: #CC2; +} + +/* CSS overrides for treeview */ +.expand-icon { + font-size: 11px; +} + +.treeview .badge { + font-size: 10px; +} + +.treeview .list-group-item { + padding: 6px 12px; +} + +.list-group-item-condensed { + padding: 5px 10px; +} + +/* Extra label styles */ + +.label-large { + margin: 3px; + font-size: 100%; + border: 3px solid; + border-radius: 15px; + background: none; + padding-right: 10px; + padding-left: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + +.label-large-red { + color: var(--label-red); + border-color: var(--label-red); +} + +.label-red { + background: var(--label-red); +} + +.label-large-blue { + color: var(--label-blue); + border-color: var(--label-blue); +} + +.label-blue { + background: var(--label-blue); +} + +.label-large-green { + color: var(--label-green); + border-color: var(--label-green); +} + +.label-green { + background: var(--label-green); +} + +.label-large-grey { + color: var(--label-grey); + border-color: var(--label-grey); +} + +.label-grey { + background: var(--label-grey); +} + +.label-large-yellow { + color: var(--label-yellow); + border-color: var(--label-yellow); +} + +.label-yellow { + background: var(--label-yellow); +} + +.label-right { + float: right; + margin-left: 3px; + margin-right: 3px; +} + +/* Bootstrap table overrides */ + +.stock-sub-group td { + background-color: #ebf4f4; +} + +.sub-table { + margin-left: 45px; + margin-right: 45px; +} + +.detail-icon .glyphicon { + color: #98d296; +} + +/* Force select2 elements in modal forms to be full width */ +.select-full-width { + width: 100%; +} + +.basecurrency { + color: #050; + font-style: italic; + font-weight: bold; +} + +.bomselect { + max-width: 250px; +} + +.rowvalid { + color: #050; +} + +.rowinvalid { + color: #A00; + font-style: italic; +} + +.dropdown { + padding-left: 1px; + margin-left: 1px; +} + +.dropdown-buttons { + display: inline-block +} + +.dropdown-menu .open{ + z-index: 1000; + position: relative; + overflow: visible; +} + +/* Styles for table buttons and filtering */ +.button-toolbar .btn { + margin-left: 1px; + margin-right: 1px; +} + +.filter-list { + display: inline-block; + *display: inline; + margin-bottom: 1px; + margin-top: 1px; + vertical-align: middle; + margin: 1px; + padding: 2px; + background: #eee; + border: 1px solid #eee; + border-radius: 3px; +} + +.filter-list .close { + cursor: pointer; + right: 0%; + padding-right: 2px; + padding-left: 2px; + transform: translate(0%, -25%); +} + +.filter-list .close:hover {background: #bbb;} + +.filter-tag { + display: inline-block; + *display: inline; + zoom: 1; + padding-left: 3px; + padding-right: 3px; + padding-top: 2px; + padding-bottom: 2px; + border: 1px solid #aaa; + border-radius: 3px; + background: #eee; + margin: 1px; + margin-left: 5px; + margin-right: 5px; +} + +.filter-input { + display: inline-block; + *display: inline; + zoom: 1; +} + +.filter-tag:hover { + background: #ddd; +} + +/* Part image icons with full-display on mouse hover */ + +.hover-img-thumb { + background: #eee; + width: 28px; + height: 28px; + object-fit: contain; + border: 1px solid #cce; +} + +.hover-img-large { + background: #eee; + display: none; + position: absolute; + z-index: 400; + border: 1px solid #555; + max-width: 250px; +} + +.hover-icon { + margin-right: 10px; +} + +.hover-icon:hover > .hover-img-large { + display: block; +} + +/* dropzone class - for Drag-n-Drop file uploads */ +.dropzone { + z-index: 2; +} + +/* +.dropzone * { + pointer-events: none; +} +*/ + +.dragover { + background-color: #55A; + border: 1px dashed #111; + opacity: 0.1; + -moz-opacity: 10%; + -webkit-opacity: 10%; +} + +/* grid display for part images */ + +.table-img-grid tr { + display: inline; +} + +.table-img-grid td { + padding: 10px; + margin: 10px; +} + +.table-img-grid .grid-image { + + height: 128px; + width: 128px; + object-fit: contain; + background: #eee; +} + +.btn-glyph { + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + padding-bottom: 2px; +} + +.action-button { + font-size: 125%; +} + +.action-buttons .btn { + font-size: 175%; + align-content: center; + vertical-align: middle; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + padding-bottom: 2px; +}; + +.panel-heading .badge { + float: right; +} + +.badge { + float: right; + background-color: #777; + color: #fff; + border-radius: 5px; + margin-left: 10px; +} + +.badge-alert { + background-color: #f33; +} + +.part-thumb { + width: 200px; + height: 200px; + margin: 2px; + padding: 3px; + object-fit: contain; + border: 1px solid #aaa; + border-radius: 3px; +} + +.part-thumb-container:hover .part-thumb-overlay { + opacity: 1; +} + +.part-thumb-overlay { + position: absolute; + top: 0; + left: 0; + opacity: 0; + transition: .25s ease; + padding: 15px; + margin: 5px; +} + +.checkbox { + margin-left: 20px; +} + +.checkboxinput { + padding-left: 5px; + padding-right: 5px; +} + +.media { + padding-top: 15px; +} + +.media-body { + padding-top: 10px; + overflow: visible; +} + +.navigation { +} + +.nav-tabs { + margin-bottom: 20px; +} + +.settings-container { + width: 90%; + padding: 15px; +} + +.settings-nav { + height: 100%; + width: 160px; + position: fixed; + z-index: 1; + //top: 0; + //left: 0; + overflow-x: hidden; + padding-top: 20px; + padding-right: 25px; +} + +.settings-content { + margin-left: 175px; + padding: 0px 10px; +} + +.breadcrump { + margin-bottom: 5px; +} + +.inventree-body { + width: 100%; + padding: 5px; + margin: 10px; +} + +.inventree-pre-content { + width: 100%; + clear: both; +} + +.inventree-content { + padding-left: 5px; + padding-right: 5px; + padding-top: 5px; + width: auto; + transition: 0.1s; +} + +.body { + padding-top: 70px; +} + +.modal { + overflow: hidden; + z-index: 9999; +} + +.modal-primary { + z-index: 10000; +} + +.modal-secondary { + z-index: 11000; +} + +.js-modal-form .checkbox { + margin-left: 0px; +} + +.modal-dialog { + width: 60%; +} + +.modal-secondary .modal-dialog { + width: 40%; + padding-top: 15px; +} + +.modal-content h3 { + margin-top: 3px; + margin-bottom: 3px; +} + +.modal-form-content { + border-radius: 0; + position:relative; + height: auto !important; + max-height: calc(100vh - 200px) !important; + overflow-y: scroll; + padding: 10px; +} + +.modal input { + width: 100%; +} + +input[type="submit"] { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} + +.modal textarea { + width: 100%; +} + +/* Force a control-label div to be 100% width */ +.modal .control-label { + width: 100%; + margin-top: 5px; +} + +.modal .control-label .btn { + padding-top: 3px; + padding-bottom: 3px; +} + +.modal .btn-secondary { + background-color: #5e7d87; +} + +/* The side navigation menu */ +.sidenav { + height: 100%; /* 100% Full-height */ + width: 0px; /* 0 width - change this with JavaScript */ + position: fixed; /* Stay in place */ + background-color: #fff; /* Black*/ + overflow-x: hidden; /* Disable horizontal scroll */ + transition: 0.1s; /* 0.5 second transition effect to slide in the sidenav */ +} + +.wrapper { + align-items: stretch; + display: flex; +} + +.help-inline { + color: #A11; +} + +.notification-area { + position: fixed; + top: 0px; + margin-top: 20px; + width: 100%; + padding: 20px; + z-index: 5000; + pointer-events: none; // Prevent this div from blocking links underneath +} + +.alert { + display: none; + border-radius: 5px; + opacity: 0.9; + pointer-events: all; +} + +.alert-block { + display: block; +} + +.btn { + margin-left: 2px; + margin-right: 2px; +} + +.btn-remove { + padding: 3px; + padding-left: 5px; + padding-right: 5px; + color: #A11; +} + +.btn-create { + padding: 3px; + padding-left: 5px; + padding-right: 5px; + color: #1A1; +} + +.btn-edit { + padding: 3px; + padding: 3px; + padding-left: 5px; + padding-right: 5px; + color: #55E; +} + +.button-toolbar { + padding-left: 0px; +} + +.panel-group { + margin-bottom: 5px; +} + +.panel-body { + padding: 10px; +} + +.panel-group .panel { + border-radius: 2px; +} + +.panel-heading { + padding: 5px 10px; + background-color: #fafafa; +} + +.float-right { + float: right; +} + +.warning-msg { + color: #e00; +} + +.login { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.part-allocation { + padding: 3px 10px; + border: 1px solid #ccc; + border-radius: 2px; +} + +.part-allocation-pass { + background-color: #dbf0db; +} + +.part-allocation-underallocated { + background-color: #f0dbdb; +} + +.part-allocation-overallocated { + background-color: #ccf5ff; +} + +.glyphicon-refresh-animate { + -animation: spin .7s infinite linear; + -webkit-animation: spin2 .7s infinite linear; +} + +@-webkit-keyframes spin2 { + from { -webkit-transform: rotate(0deg);} + to { -webkit-transform: rotate(360deg);} +} + +@keyframes spin { + from { transform: scale(1) rotate(0deg);} + to { transform: scale(1) rotate(360deg);} +} + diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index d0076714ae..0ada05753c 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -36,7 +36,7 @@ from django.views.generic.base import RedirectView from rest_framework.documentation import include_docs_urls from .views import IndexView, SearchView, DatabaseStatsView -from .views import SettingsView, EditUserView, SetPasswordView +from .views import SettingsView, EditUserView, SetPasswordView, ThemeSelectView from .views import DynamicJsView from .api import InfoView @@ -71,6 +71,7 @@ settings_urls = [ url(r'^user/?', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings-user'), url(r'^currency/?', SettingsView.as_view(template_name='InvenTree/settings/currency.html'), name='settings-currency'), url(r'^part/?', SettingsView.as_view(template_name='InvenTree/settings/part.html'), name='settings-part'), + url(r'^theme/?', ThemeSelectView.as_view(), name='settings-theme'), url(r'^other/?', SettingsView.as_view(template_name='InvenTree/settings/other.html'), name='settings-other'), # Catch any other urls diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 333f11898b..a6b7c6cd26 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -11,16 +11,17 @@ from __future__ import unicode_literals from django.utils.translation import gettext_lazy as _ from django.template.loader import render_to_string from django.http import JsonResponse, HttpResponseRedirect +from django.urls import reverse_lazy from django.views import View -from django.views.generic import UpdateView, CreateView +from django.views.generic import UpdateView, CreateView, FormView from django.views.generic.base import TemplateView from part.models import Part, PartCategory from stock.models import StockLocation, StockItem -from common.models import InvenTreeSetting +from common.models import InvenTreeSetting, Theme -from .forms import DeleteForm, EditUserForm, SetPasswordForm +from .forms import DeleteForm, EditUserForm, SetPasswordForm, ThemeSelectForm from .helpers import str2bool from rest_framework import views @@ -556,6 +557,14 @@ class SettingsView(TemplateView): return ctx +class ThemeSelectView(FormView): + """ View for selecting a color theme """ + + form_class = ThemeSelectForm + success_url = reverse_lazy('settings-theme') + template_name = "InvenTree/settings/theme.html" + + class DatabaseStatsView(AjaxView): """ View for displaying database statistics """ diff --git a/InvenTree/common/migrations/0007_theme.py b/InvenTree/common/migrations/0007_theme.py new file mode 100644 index 0000000000..9af751af05 --- /dev/null +++ b/InvenTree/common/migrations/0007_theme.py @@ -0,0 +1,20 @@ +# Generated by Django 3.0.7 on 2020-09-07 16:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0006_auto_20200203_0951'), + ] + + operations = [ + migrations.CreateModel( + name='Theme', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('theme', models.IntegerField(choices=[(0, 'Default'), (1, 'Darker')], default=0)), + ], + ), + ] diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 6a2f6d8fa3..ef1778cb87 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -154,3 +154,17 @@ class Currency(models.Model): self.value = 1.0 super().save(*args, **kwargs) + + +class Theme(models.Model): + """ Color Theme setting """ + + class ThemeChoices(models.IntegerChoices): + DEFAULT = 0, _('Default') + DARKER = 1, _('Darker') + + theme = models.IntegerField(choices=ThemeChoices.choices, + default=ThemeChoices.DEFAULT) + + def __str__(self): + return self.theme diff --git a/InvenTree/templates/InvenTree/settings/tabs.html b/InvenTree/templates/InvenTree/settings/tabs.html index 7b049e4fc6..8719d29c81 100644 --- a/InvenTree/templates/InvenTree/settings/tabs.html +++ b/InvenTree/templates/InvenTree/settings/tabs.html @@ -8,6 +8,9 @@ Part + + Theme + {% if user.is_staff %} Other diff --git a/InvenTree/templates/InvenTree/settings/theme.html b/InvenTree/templates/InvenTree/settings/theme.html new file mode 100644 index 0000000000..234b8e1cd3 --- /dev/null +++ b/InvenTree/templates/InvenTree/settings/theme.html @@ -0,0 +1,27 @@ +{% extends "InvenTree/settings/settings.html" %} + +{% block tabs %} +{% include "InvenTree/settings/tabs.html" with tab='theme' %} +{% endblock %} + +{% block settings %} + +
+
+

Color Themes

+
+
+ +
+
+
+
+ {% csrf_token %} + {{ form }} + +
+
+
+
+ +{% endblock %} \ No newline at end of file From 2e5ec5d24903f8e1681c291115ca8188f4cf4a2c Mon Sep 17 00:00:00 2001 From: eeintech Date: Mon, 7 Sep 2020 15:15:51 -0500 Subject: [PATCH 2/7] Theme change works but applies to all user --- InvenTree/InvenTree/forms.py | 16 ++++++++++-- InvenTree/InvenTree/views.py | 26 +++++++++++++++++++ InvenTree/common/migrations/0007_theme.py | 4 +-- InvenTree/common/models.py | 14 +++++----- .../part/templatetags/inventree_extras.py | 10 +++++-- .../templates/InvenTree/settings/theme.html | 9 ++++--- InvenTree/templates/base.html | 3 ++- 7 files changed, 65 insertions(+), 17 deletions(-) diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index e090ab9de3..2937ad5651 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -9,7 +9,7 @@ from django.utils.translation import ugettext as _ from django import forms from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout, Field -from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText +from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText, StrictButton from django.contrib.auth.models import User from common.models import Theme @@ -171,4 +171,16 @@ class ThemeSelectForm(forms.ModelForm): model = Theme fields = [ 'theme' - ] \ No newline at end of file + ] + + def __init__(self, *args, **kwargs): + super(ThemeSelectForm, self).__init__(*args, **kwargs) + self.helper = FormHelper() + # Form rendering + self.helper.form_show_labels = False + self.helper.form_class = 'form-inline' + # self.helper.field_template = 'bootstrap4/layout/inline_field.html' + self.helper.layout = Layout( + Field('theme'), + StrictButton(_('Apply Theme'), css_class='btn btn-primary', type='submit') + ) \ No newline at end of file diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index a6b7c6cd26..0fd81698e7 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -564,6 +564,32 @@ class ThemeSelectView(FormView): success_url = reverse_lazy('settings-theme') template_name = "InvenTree/settings/theme.html" + def get_initial(self): + """ Select user theme """ + initial = super(ThemeSelectView, self).get_initial() + initial['theme'] = Theme.objects.all().get().theme + return initial + + def post(self, request, *args, **kwargs): + """ Save user color theme """ + form = self.get_form() + if form.is_valid(): + theme_select = form.cleaned_data['theme'] + + try: + user_theme = Theme.objects.all().get() + except Theme.DoesNotExist: + print('No theme selected yet') + user_theme = Theme() + + # Set color theme + user_theme.theme = theme_select + user_theme.save() + + return self.form_valid(form) + else: + return self.form_invalid(form) + class DatabaseStatsView(AjaxView): """ View for displaying database statistics """ diff --git a/InvenTree/common/migrations/0007_theme.py b/InvenTree/common/migrations/0007_theme.py index 9af751af05..ca763b0b07 100644 --- a/InvenTree/common/migrations/0007_theme.py +++ b/InvenTree/common/migrations/0007_theme.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.7 on 2020-09-07 16:12 +# Generated by Django 3.0.7 on 2020-09-07 20:12 from django.db import migrations, models @@ -14,7 +14,7 @@ class Migration(migrations.Migration): name='Theme', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('theme', models.IntegerField(choices=[(0, 'Default'), (1, 'Darker')], default=0)), + ('theme', models.CharField(blank=True, choices=[('', 'Default'), ('-darker', 'Darker')], default='', max_length=20)), ], ), ] diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index ef1778cb87..b696c5486a 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -159,12 +159,12 @@ class Currency(models.Model): class Theme(models.Model): """ Color Theme setting """ - class ThemeChoices(models.IntegerChoices): - DEFAULT = 0, _('Default') - DARKER = 1, _('Darker') + class ThemeChoices(models.TextChoices): + DEFAULT = '', _('Default') + DARKER = '-darker', _('Darker') - theme = models.IntegerField(choices=ThemeChoices.choices, - default=ThemeChoices.DEFAULT) + theme = models.CharField(max_length=20, + choices=ThemeChoices.choices, + default=ThemeChoices.DEFAULT, + blank=True) - def __str__(self): - return self.theme diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 8fa63adc0f..d2a4f66607 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -3,10 +3,10 @@ over and above the built-in Django tags. """ from django import template -from InvenTree import version +from InvenTree import version, settings from InvenTree.helpers import decimal2string -from common.models import InvenTreeSetting +from common.models import InvenTreeSetting, Theme register = template.Library() @@ -88,3 +88,9 @@ def inventree_docs_url(*args, **kwargs): @register.simple_tag() def inventree_setting(key, *args, **kwargs): return InvenTreeSetting.get_setting(key) + + +@register.simple_tag() +def get_theme_css(): + user_theme = Theme.objects.all().get().theme + return f'{settings.STATIC_URL}css/inventree' + user_theme + '.css' diff --git a/InvenTree/templates/InvenTree/settings/theme.html b/InvenTree/templates/InvenTree/settings/theme.html index 234b8e1cd3..e09739671b 100644 --- a/InvenTree/templates/InvenTree/settings/theme.html +++ b/InvenTree/templates/InvenTree/settings/theme.html @@ -1,4 +1,6 @@ {% extends "InvenTree/settings/settings.html" %} +{% load i18n %} +{% load inventree_extras %} {% block tabs %} {% include "InvenTree/settings/tabs.html" with tab='theme' %} @@ -16,9 +18,10 @@
- {% csrf_token %} - {{ form }} - + {% csrf_token %} + {% load crispy_forms_tags %} + {% crispy form %} +{# #}
diff --git a/InvenTree/templates/base.html b/InvenTree/templates/base.html index ca2ab83f36..1b4cfd0af9 100644 --- a/InvenTree/templates/base.html +++ b/InvenTree/templates/base.html @@ -1,5 +1,6 @@ {% load static %} {% load i18n %} +{% load inventree_extras %} @@ -38,7 +39,7 @@ - + {% block css %} {% endblock %} From 10dd8fad80afe542b1de58a35517990ba2df882b Mon Sep 17 00:00:00 2001 From: eeintech Date: Mon, 7 Sep 2020 16:27:23 -0500 Subject: [PATCH 3/7] Renamed Theme to ColorTheme, ColorTheme is now a per-user selection --- InvenTree/InvenTree/forms.py | 17 ++++---- InvenTree/InvenTree/urls.py | 4 +- InvenTree/InvenTree/views.py | 40 ++++++++++++------- .../{0007_theme.py => 0007_colortheme.py} | 7 ++-- InvenTree/common/models.py | 13 +++--- .../part/templatetags/inventree_extras.py | 9 +++-- .../templates/InvenTree/settings/theme.html | 3 +- InvenTree/templates/base.html | 2 +- 8 files changed, 56 insertions(+), 39 deletions(-) rename InvenTree/common/migrations/{0007_theme.py => 0007_colortheme.py} (58%) diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index 2937ad5651..24270e0617 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -11,7 +11,8 @@ from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout, Field from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText, StrictButton from django.contrib.auth.models import User -from common.models import Theme +from common.models import ColorTheme + class HelperForm(forms.ModelForm): """ Provides simple integration of crispy_forms extension. """ @@ -163,24 +164,24 @@ class SetPasswordForm(HelperForm): ] -class ThemeSelectForm(forms.ModelForm): +class ColorThemeSelectForm(forms.ModelForm): """ Form for setting color theme """ class Meta: - model = Theme + model = ColorTheme fields = [ - 'theme' + 'name' ] def __init__(self, *args, **kwargs): - super(ThemeSelectForm, self).__init__(*args, **kwargs) + super(ColorThemeSelectForm, self).__init__(*args, **kwargs) self.helper = FormHelper() # Form rendering self.helper.form_show_labels = False self.helper.form_class = 'form-inline' # self.helper.field_template = 'bootstrap4/layout/inline_field.html' self.helper.layout = Layout( - Field('theme'), - StrictButton(_('Apply Theme'), css_class='btn btn-primary', type='submit') - ) \ No newline at end of file + Field('name'), + StrictButton(_('Apply Theme'), css_class='btn btn-primary', type='submit') + ) diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 0ada05753c..c433cef382 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -36,7 +36,7 @@ from django.views.generic.base import RedirectView from rest_framework.documentation import include_docs_urls from .views import IndexView, SearchView, DatabaseStatsView -from .views import SettingsView, EditUserView, SetPasswordView, ThemeSelectView +from .views import SettingsView, EditUserView, SetPasswordView, ColorThemeSelectView from .views import DynamicJsView from .api import InfoView @@ -71,7 +71,7 @@ settings_urls = [ url(r'^user/?', SettingsView.as_view(template_name='InvenTree/settings/user.html'), name='settings-user'), url(r'^currency/?', SettingsView.as_view(template_name='InvenTree/settings/currency.html'), name='settings-currency'), url(r'^part/?', SettingsView.as_view(template_name='InvenTree/settings/part.html'), name='settings-part'), - url(r'^theme/?', ThemeSelectView.as_view(), name='settings-theme'), + url(r'^theme/?', ColorThemeSelectView.as_view(), name='settings-theme'), url(r'^other/?', SettingsView.as_view(template_name='InvenTree/settings/other.html'), name='settings-other'), # Catch any other urls diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 0fd81698e7..69649edad9 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -19,9 +19,9 @@ from django.views.generic.base import TemplateView from part.models import Part, PartCategory from stock.models import StockLocation, StockItem -from common.models import InvenTreeSetting, Theme +from common.models import InvenTreeSetting, ColorTheme -from .forms import DeleteForm, EditUserForm, SetPasswordForm, ThemeSelectForm +from .forms import DeleteForm, EditUserForm, SetPasswordForm, ColorThemeSelectForm from .helpers import str2bool from rest_framework import views @@ -557,33 +557,45 @@ class SettingsView(TemplateView): return ctx -class ThemeSelectView(FormView): +class ColorThemeSelectView(FormView): """ View for selecting a color theme """ - form_class = ThemeSelectForm + form_class = ColorThemeSelectForm success_url = reverse_lazy('settings-theme') template_name = "InvenTree/settings/theme.html" + def get_user_theme(self): + """ Get user color theme """ + try: + user_theme = ColorTheme.objects.filter(user=self.request.user).get() + except ColorTheme.DoesNotExist: + user_theme = None + + return user_theme + def get_initial(self): """ Select user theme """ - initial = super(ThemeSelectView, self).get_initial() - initial['theme'] = Theme.objects.all().get().theme + initial = super(ColorThemeSelectView, self).get_initial() + user_theme = self.get_user_theme() + if user_theme: + initial['name'] = user_theme.name return initial def post(self, request, *args, **kwargs): """ Save user color theme """ form = self.get_form() if form.is_valid(): - theme_select = form.cleaned_data['theme'] + theme_select = form.cleaned_data['name'] + # Get current user theme + user_theme = self.get_user_theme() - try: - user_theme = Theme.objects.all().get() - except Theme.DoesNotExist: - print('No theme selected yet') - user_theme = Theme() + # Create theme entry if user did not select one yet + if not user_theme: + user_theme = ColorTheme() - # Set color theme - user_theme.theme = theme_select + # Set color theme to form selection + user_theme.user = str(request.user) + user_theme.name = theme_select user_theme.save() return self.form_valid(form) diff --git a/InvenTree/common/migrations/0007_theme.py b/InvenTree/common/migrations/0007_colortheme.py similarity index 58% rename from InvenTree/common/migrations/0007_theme.py rename to InvenTree/common/migrations/0007_colortheme.py index ca763b0b07..b0455073a0 100644 --- a/InvenTree/common/migrations/0007_theme.py +++ b/InvenTree/common/migrations/0007_colortheme.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.7 on 2020-09-07 20:12 +# Generated by Django 3.0.7 on 2020-09-07 21:13 from django.db import migrations, models @@ -11,10 +11,11 @@ class Migration(migrations.Migration): operations = [ migrations.CreateModel( - name='Theme', + name='ColorTheme', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('theme', models.CharField(blank=True, choices=[('', 'Default'), ('-darker', 'Darker')], default='', max_length=20)), + ('name', models.CharField(blank=True, choices=[('', 'Default'), ('-darker', 'Darker')], default='', max_length=20)), + ('user', models.CharField(max_length=150)), ], ), ] diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index b696c5486a..04c0082489 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -156,15 +156,16 @@ class Currency(models.Model): super().save(*args, **kwargs) -class Theme(models.Model): +class ColorTheme(models.Model): """ Color Theme setting """ - class ThemeChoices(models.TextChoices): + class ColorThemeChoices(models.TextChoices): DEFAULT = '', _('Default') DARKER = '-darker', _('Darker') - theme = models.CharField(max_length=20, - choices=ThemeChoices.choices, - default=ThemeChoices.DEFAULT, - blank=True) + name = models.CharField(max_length=20, + choices=ColorThemeChoices.choices, + default=ColorThemeChoices.DEFAULT, + blank=True) + user = models.CharField(max_length=150) \ No newline at end of file diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index d2a4f66607..0026c5e7f8 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -6,7 +6,7 @@ from django import template from InvenTree import version, settings from InvenTree.helpers import decimal2string -from common.models import InvenTreeSetting, Theme +from common.models import InvenTreeSetting, ColorTheme register = template.Library() @@ -91,6 +91,9 @@ def inventree_setting(key, *args, **kwargs): @register.simple_tag() -def get_theme_css(): - user_theme = Theme.objects.all().get().theme +def get_theme_css(username): + try: + user_theme = ColorTheme.objects.filter(user=username).get().name + except ColorTheme.DoesNotExist: + user_theme = '' return f'{settings.STATIC_URL}css/inventree' + user_theme + '.css' diff --git a/InvenTree/templates/InvenTree/settings/theme.html b/InvenTree/templates/InvenTree/settings/theme.html index e09739671b..55d6745281 100644 --- a/InvenTree/templates/InvenTree/settings/theme.html +++ b/InvenTree/templates/InvenTree/settings/theme.html @@ -21,10 +21,9 @@ {% csrf_token %} {% load crispy_forms_tags %} {% crispy form %} -{# #} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/InvenTree/templates/base.html b/InvenTree/templates/base.html index 1b4cfd0af9..b622fbed26 100644 --- a/InvenTree/templates/base.html +++ b/InvenTree/templates/base.html @@ -39,7 +39,7 @@ - + {% block css %} {% endblock %} From 8e2d568a4239125bb0efc75542e00a2a0190952b Mon Sep 17 00:00:00 2001 From: eeintech Date: Mon, 7 Sep 2020 17:01:05 -0500 Subject: [PATCH 4/7] Style correction (missing ending new line), removed commented line in ColorThemeSelectForm --- InvenTree/InvenTree/forms.py | 1 - InvenTree/common/models.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index 24270e0617..d023482f2f 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -180,7 +180,6 @@ class ColorThemeSelectForm(forms.ModelForm): # Form rendering self.helper.form_show_labels = False self.helper.form_class = 'form-inline' - # self.helper.field_template = 'bootstrap4/layout/inline_field.html' self.helper.layout = Layout( Field('name'), StrictButton(_('Apply Theme'), css_class='btn btn-primary', type='submit') diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 04c0082489..2b7eeb497c 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -168,4 +168,4 @@ class ColorTheme(models.Model): default=ColorThemeChoices.DEFAULT, blank=True) - user = models.CharField(max_length=150) \ No newline at end of file + user = models.CharField(max_length=150) From 896fa131f037e47a194836acaba319ff59d3fffb Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 8 Sep 2020 16:24:22 -0500 Subject: [PATCH 5/7] Moved color themes CSS sheets to own folder, nicer crispy form for selecting theme --- InvenTree/InvenTree/forms.py | 17 +- .../static/css/color-themes/dark-reader.css | 2793 +++++++++++++++++ .../static/css/color-themes/darker.css | 42 + .../static/css/color-themes/default.css | 1 + .../InvenTree/static/css/inventree-darker.css | 785 ----- InvenTree/common/models.py | 5 +- .../part/templatetags/inventree_extras.py | 16 +- .../templates/InvenTree/settings/theme.html | 16 +- InvenTree/templates/base.html | 3 +- 9 files changed, 2870 insertions(+), 808 deletions(-) create mode 100644 InvenTree/InvenTree/static/css/color-themes/dark-reader.css create mode 100644 InvenTree/InvenTree/static/css/color-themes/darker.css create mode 100644 InvenTree/InvenTree/static/css/color-themes/default.css delete mode 100644 InvenTree/InvenTree/static/css/inventree-darker.css diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index d023482f2f..87381b775a 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -9,7 +9,7 @@ from django.utils.translation import ugettext as _ from django import forms from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout, Field -from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText, StrictButton +from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText, StrictButton, Div from django.contrib.auth.models import User from common.models import ColorTheme @@ -165,8 +165,7 @@ class SetPasswordForm(HelperForm): class ColorThemeSelectForm(forms.ModelForm): - """ Form for setting color theme - """ + """ Form for setting color theme """ class Meta: model = ColorTheme @@ -179,8 +178,14 @@ class ColorThemeSelectForm(forms.ModelForm): self.helper = FormHelper() # Form rendering self.helper.form_show_labels = False - self.helper.form_class = 'form-inline' self.helper.layout = Layout( - Field('name'), - StrictButton(_('Apply Theme'), css_class='btn btn-primary', type='submit') + Div( + Div(Field('name'), + css_class='col-sm-6', + style='width: 200px;'), + Div(StrictButton(_('Apply Theme'), css_class='btn btn-primary', type='submit'), + css_class='col-sm-6', + style='width: auto;'), + css_class='row', + ), ) diff --git a/InvenTree/InvenTree/static/css/color-themes/dark-reader.css b/InvenTree/InvenTree/static/css/color-themes/dark-reader.css new file mode 100644 index 0000000000..7cfe578cf5 --- /dev/null +++ b/InvenTree/InvenTree/static/css/color-themes/dark-reader.css @@ -0,0 +1,2793 @@ +/* Color Theme: "Dark Reader" (Autogenerated) */ + +/* + _______ + / \ + .==. .==. + (( ))==(( )) + / "==" "=="\ + /____|| || ||___\ + ________ ____ ________ ___ ___ + | ___ \ / \ | ___ \ | | / / + | | \ \ / /\ \ | | \ \| |_/ / + | | ) / /__\ \ | |__/ /| ___ \ + | |__/ / ______ \| ____ \| | \ \ +_______|_______/__/ ____ \__\__|___\__\__|___\__\____ +| ___ \ | ____/ / \ | ___ \ | ____| ___ \ +| | \ \| |___ / /\ \ | | \ \| |___| | \ \ +| |__/ /| ____/ /__\ \ | | ) | ____| |__/ / +| ____ \| |__/ ______ \| |__/ /| |___| ____ \ +|__| \__\____/__/ \__\_______/ |______|__| \__\ + https://darkreader.org +*/ +/* User-Agent Style */ +html { + background-color: #181a1b !important; +} +html, body, input, textarea, select, button { + background-color: #181a1b; +} +html, body, input, textarea, select, button { + border-color: #736b5e; + color: #e8e6e3; +} +a { + color: #3391ff; +} +table { + border-color: #545b5e; +} +::placeholder { + color: #b2aba1; +} +input:-webkit-autofill, +textarea:-webkit-autofill, +select:-webkit-autofill { + background-color: #555b00 !important; + color: #e8e6e3 !important; +} +::-webkit-scrollbar { + background-color: #202324; + color: #aba499; +} +::-webkit-scrollbar-thumb { + background-color: #454a4d; +} +::-webkit-scrollbar-thumb:hover { + background-color: #575e62; +} +::-webkit-scrollbar-thumb:active { + background-color: #484e51; +} +::-webkit-scrollbar-corner { + background-color: #181a1b; +} +* { + scrollbar-color: #202324 #454a4d; +} +::selection { + background-color: #004daa !important; + color: #e8e6e3 !important; +} +::-moz-selection { + background-color: #004daa !important; + color: #e8e6e3 !important; +} + +/* Invert Style */ +.jfk-bubble.gtx-bubble { + filter: invert(100%) hue-rotate(180deg) contrast(90%) !important; +} + +/* Override Style */ +.vimvixen-hint { + background-color: #7b5300 !important; + border-color: #d8b013 !important; + color: #f3e8c8 !important; +} +::placeholder { + opacity: 0.5 !important; +} + +/* Variables Style */ +:root { + --darkreader-neutral-background: #181a1b; + --darkreader-neutral-text: #e8e6e3; + --darkreader-selection-background: #004daa; + --darkreader-selection-text: #e8e6e3; +} + +/* Modified CSS */ +.fa-layers-counter { + background-color: rgb(182, 0, 18); + color: rgb(232, 230, 227); +} +.fa-border { + border-color: rgb(53, 57, 59); +} +.fa-inverse { + color: rgb(232, 230, 227); +} +.sr-only { + border-color: initial; +} +.svg-inline--fa .fa-primary { + fill: currentcolor; +} +.svg-inline--fa .fa-secondary { + fill: currentcolor; +} +.svg-inline--fa mask .fa-primary, +.svg-inline--fa mask .fa-secondary { + fill: rgb(232, 230, 227); +} +.fad.fa-inverse { + color: rgb(232, 230, 227); +} +.treegrid-expander-expanded { + background-image: url("http://127.0.0.1:8000/static/treegrid/img/collapse.png"); +} +.treegrid-expander-collapsed { + background-image: url("http://127.0.0.1:8000/static/treegrid/img/expand.png"); +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline-color: initial; +} +abbr[title] { + border-bottom-color: initial; +} +mark { + color: rgb(232, 230, 227); + background-image: initial; + background-color: rgb(204, 204, 0); +} +img { + border-color: initial; +} +button, +input, +optgroup, +select, +textarea { + color: inherit; +} +fieldset { + border-color: rgb(66, 71, 74); +} +legend { + border-color: initial; +} +html { + -webkit-tap-highlight-color: rgba(232, 230, 227, 0); +} +body { + color: rgb(200, 195, 188); + background-color: rgb(24, 26, 27); +} +a { + color: rgb(105, 166, 213); + text-decoration-color: initial; +} +a:focus, +a:hover { + color: rgb(141, 187, 223); + text-decoration-color: initial; +} +a:focus { + outline-color: rgb(186, 123, 0); +} +.img-thumbnail { + background-color: rgb(24, 26, 27); + border-color: rgb(58, 62, 65); +} +hr { + border-right-color: initial; + border-bottom-color: initial; + border-left-color: initial; + border-top-color: rgb(53, 57, 59); +} +.sr-only { + border-color: initial; +} +.h1, +.h2, +.h3, +.h4, +.h5, +.h6, +h1, +h2, +h3, +h4, +h5, +h6 { + color: inherit; +} +.h1 .small, +.h1 small, +.h2 .small, +.h2 small, +.h3 .small, +.h3 small, +.h4 .small, +.h4 small, +.h5 .small, +.h5 small, +.h6 .small, +.h6 small, +h1 .small, +h1 small, +h2 .small, +h2 small, +h3 .small, +h3 small, +h4 .small, +h4 small, +h5 .small, +h5 small, +h6 .small, +h6 small { + color: rgb(157, 148, 136); +} +.mark, +mark { + background-color: rgb(63, 54, 7); +} +.text-muted { + color: rgb(157, 148, 136); +} +.text-primary { + color: rgb(105, 166, 213); +} +a.text-primary:focus, +a.text-primary:hover { + color: rgb(129, 180, 220); +} +.text-success { + color: rgb(139, 196, 140); +} +a.text-success:focus, +a.text-success:hover { + color: rgb(162, 208, 164); +} +.text-info { + color: rgb(117, 178, 208); +} +a.text-info:focus, +a.text-info:hover { + color: rgb(144, 192, 217); +} +.text-warning { + color: rgb(198, 171, 123); +} +a.text-warning:focus, +a.text-warning:hover { + color: rgb(209, 187, 148); +} +.text-danger { + color: rgb(194, 102, 100); +} +a.text-danger:focus, +a.text-danger:hover { + color: rgb(204, 127, 126); +} +.bg-primary { + color: rgb(232, 230, 227); + background-color: rgb(41, 98, 146); +} +a.bg-primary:focus, +a.bg-primary:hover { + background-color: rgb(32, 77, 115); +} +.bg-success { + background-color: rgb(41, 60, 23); +} +a.bg-success:focus, +a.bg-success:hover { + background-color: rgb(56, 83, 31); +} +.bg-info { + background-color: rgb(14, 48, 65); +} +a.bg-info:focus, +a.bg-info:hover { + background-color: rgb(19, 66, 90); +} +.bg-warning { + background-color: rgb(63, 54, 7); +} +a.bg-warning:focus, +a.bg-warning:hover { + background-color: rgb(90, 77, 10); +} +.bg-danger { + background-color: rgb(56, 22, 22); +} +a.bg-danger:focus, +a.bg-danger:hover { + background-color: rgb(79, 30, 30); +} +.page-header { + border-bottom-color: rgb(53, 57, 59); +} +.list-unstyled { + list-style-image: initial; +} +.list-inline { + list-style-image: initial; +} +abbr[data-original-title], +abbr[title] { + border-bottom-color: rgb(101, 94, 83); +} +blockquote { + border-left-color: rgb(53, 57, 59); +} +blockquote .small, +blockquote footer, +blockquote small { + color: rgb(157, 148, 136); +} +.blockquote-reverse, +blockquote.pull-right { + border-right-color: rgb(53, 57, 59); + border-left-color: initial; +} +code { + color: rgb(221, 73, 110); + background-color: rgb(43, 20, 26); +} +kbd { + color: rgb(232, 230, 227); + background-color: rgb(38, 42, 43); + box-shadow: rgba(0, 0, 0, 0.25) 0px -1px 0px inset; +} +kbd kbd { + box-shadow: none; +} +pre { + color: rgb(200, 195, 188); + background-color: rgb(30, 32, 33); + border-color: rgb(62, 68, 70); +} +pre code { + color: inherit; + background-color: transparent; +} +table { + background-color: transparent; +} +caption { + color: rgb(157, 148, 136); +} +.table > tbody > tr > td, +.table > tbody > tr > th, +.table > tfoot > tr > td, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > thead > tr > th { + border-top-color: rgb(58, 62, 65); +} +.table > thead > tr > th { + border-bottom-color: rgb(58, 62, 65); +} +.table > caption + thead > tr:first-child > td, +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > td, +.table > thead:first-child > tr:first-child > th { + border-top-color: initial; +} +.table > tbody + tbody { + border-top-color: rgb(58, 62, 65); +} +.table .table { + background-color: rgb(24, 26, 27); +} +.table-bordered { + border-color: rgb(58, 62, 65); +} +.table-bordered > tbody > tr > td, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > td, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > thead > tr > th { + border-color: rgb(58, 62, 65); +} +.table-striped > tbody > tr:nth-of-type(2n+1) { + background-color: rgb(27, 30, 31); +} +.table-hover > tbody > tr:hover { + background-color: rgb(30, 32, 33); +} +.table > tbody > tr.active > td, +.table > tbody > tr.active > th, +.table > tbody > tr > td.active, +.table > tbody > tr > th.active, +.table > tfoot > tr.active > td, +.table > tfoot > tr.active > th, +.table > tfoot > tr > td.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > thead > tr.active > th, +.table > thead > tr > td.active, +.table > thead > tr > th.active { + background-color: rgb(30, 32, 33); +} +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr.active:hover > th, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover { + background-color: rgb(37, 40, 42); +} +.table > tbody > tr.success > td, +.table > tbody > tr.success > th, +.table > tbody > tr > td.success, +.table > tbody > tr > th.success, +.table > tfoot > tr.success > td, +.table > tfoot > tr.success > th, +.table > tfoot > tr > td.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > thead > tr.success > th, +.table > thead > tr > td.success, +.table > thead > tr > th.success { + background-color: rgb(41, 60, 23); +} +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr.success:hover > th, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover { + background-color: rgb(48, 71, 27); +} +.table > tbody > tr.info > td, +.table > tbody > tr.info > th, +.table > tbody > tr > td.info, +.table > tbody > tr > th.info, +.table > tfoot > tr.info > td, +.table > tfoot > tr.info > th, +.table > tfoot > tr > td.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > thead > tr.info > th, +.table > thead > tr > td.info, +.table > thead > tr > th.info { + background-color: rgb(14, 48, 65); +} +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr.info:hover > th, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover { + background-color: rgb(44, 48, 50); +} +.table > tbody > tr.warning > td, +.table > tbody > tr.warning > th, +.table > tbody > tr > td.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr.warning > td, +.table > tfoot > tr.warning > th, +.table > tfoot > tr > td.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > thead > tr.warning > th, +.table > thead > tr > td.warning, +.table > thead > tr > th.warning { + background-color: rgb(63, 54, 7); +} +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr.warning:hover > th, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover { + background-color: rgb(77, 65, 8); +} +.table > tbody > tr.danger > td, +.table > tbody > tr.danger > th, +.table > tbody > tr > td.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr.danger > td, +.table > tfoot > tr.danger > th, +.table > tfoot > tr > td.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > thead > tr.danger > th, +.table > thead > tr > td.danger, +.table > thead > tr > th.danger { + background-color: rgb(56, 22, 22); +} +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr.danger:hover > th, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover { + background-color: rgb(67, 26, 26); +} +@media screen and (max-width: 767px) { + .table-responsive { + border-color: rgb(58, 62, 65); + } + .table-responsive > .table-bordered { + border-color: initial; + } + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > thead > tr > th:first-child { + border-left-color: initial; + } + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > thead > tr > th:last-child { + border-right-color: initial; + } + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom-color: initial; + } +} +fieldset { + border-color: initial; +} +legend { + color: rgb(200, 195, 188); + border-top-color: initial; + border-right-color: initial; + border-left-color: initial; + border-bottom-color: rgb(55, 60, 62); +} +input[type="file"]:focus, input[type="checkbox"]:focus, input[type="radio"]:focus { + outline-color: rgb(186, 123, 0); +} +output { + color: rgb(178, 172, 162); +} +.form-control { + color: rgb(178, 172, 162); + background-color: rgb(24, 26, 27); + background-image: none; + border-color: rgb(62, 68, 70); + box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset; +} +.form-control:focus { + border-color: rgb(19, 84, 135); + outline-color: initial; + box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset, + rgba(20, 85, 136, 0.6) 0px 0px 8px; +} +.form-control::-webkit-input-placeholder { + color: rgb(168, 160, 149); +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: rgb(34, 36, 38); +} +.has-success .checkbox, +.has-success .checkbox-inline, +.has-success .control-label, +.has-success .help-block, +.has-success .radio, +.has-success .radio-inline, +.has-success.checkbox label, +.has-success.checkbox-inline label, +.has-success.radio label, +.has-success.radio-inline label { + color: rgb(139, 196, 140); +} +.has-success .form-control { + border-color: rgb(68, 134, 69); + box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset; +} +.has-success .form-control:focus { + border-color: rgb(73, 143, 75); + box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset, + rgb(64, 125, 80) 0px 0px 6px; +} +.has-success .input-group-addon { + color: rgb(139, 196, 140); + background-color: rgb(41, 60, 23); + border-color: rgb(68, 134, 69); +} +.has-success .form-control-feedback { + color: rgb(139, 196, 140); +} +.has-warning .checkbox, +.has-warning .checkbox-inline, +.has-warning .control-label, +.has-warning .help-block, +.has-warning .radio, +.has-warning .radio-inline, +.has-warning.checkbox label, +.has-warning.checkbox-inline label, +.has-warning.radio label, +.has-warning.radio-inline label { + color: rgb(198, 171, 123); +} +.has-warning .form-control { + border-color: rgb(137, 108, 59); + box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset; +} +.has-warning .form-control:focus { + border-color: rgb(148, 117, 64); + box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset, + rgb(125, 98, 53) 0px 0px 6px; +} +.has-warning .input-group-addon { + color: rgb(198, 171, 123); + background-color: rgb(63, 54, 7); + border-color: rgb(137, 108, 59); +} +.has-warning .form-control-feedback { + color: rgb(198, 171, 123); +} +.has-error .checkbox, +.has-error .checkbox-inline, +.has-error .control-label, +.has-error .help-block, +.has-error .radio, +.has-error .radio-inline, +.has-error.checkbox label, +.has-error.checkbox-inline label, +.has-error.radio label, +.has-error.radio-inline label { + color: rgb(194, 102, 100); +} +.has-error .form-control { + border-color: rgb(133, 53, 52); + box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset; +} +.has-error .form-control:focus { + border-color: rgb(143, 58, 56); + box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 1px inset, + rgb(111, 45, 44) 0px 0px 6px; +} +.has-error .input-group-addon { + color: rgb(194, 102, 100); + background-color: rgb(56, 22, 22); + border-color: rgb(133, 53, 52); +} +.has-error .form-control-feedback { + color: rgb(194, 102, 100); +} +.help-block { + color: rgb(159, 151, 139); +} +.btn { + background-image: none; + border-color: transparent; +} +.btn.active.focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn:active:focus, +.btn:focus { + outline-color: rgb(186, 123, 0); +} +.btn.focus, +.btn:focus, +.btn:hover { + color: rgb(200, 195, 188); + text-decoration-color: initial; +} +.btn.active, +.btn:active { + background-image: none; + outline-color: initial; + box-shadow: rgba(0, 0, 0, 0.13) 0px 3px 5px inset; +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + box-shadow: none; +} +.btn-default { + color: rgb(200, 195, 188); + background-color: rgb(24, 26, 27); + border-color: rgb(62, 68, 70); +} +.btn-default.focus, +.btn-default:focus { + color: rgb(200, 195, 188); + background-color: rgb(38, 41, 43); + border-color: rgb(80, 87, 91); +} +.btn-default:hover { + color: rgb(200, 195, 188); + background-color: rgb(38, 41, 43); + border-color: rgb(71, 77, 80); +} +.btn-default.active, +.btn-default:active, +.open > .dropdown-toggle.btn-default { + color: rgb(200, 195, 188); + background-color: rgb(38, 41, 43); + border-color: rgb(71, 77, 80); +} +.btn-default.active.focus, +.btn-default.active:focus, +.btn-default.active:hover, +.btn-default:active.focus, +.btn-default:active:focus, +.btn-default:active:hover, +.open > .dropdown-toggle.btn-default.focus, +.open > .dropdown-toggle.btn-default:focus, +.open > .dropdown-toggle.btn-default:hover { + color: rgb(200, 195, 188); + background-color: rgb(48, 52, 54); + border-color: rgb(80, 87, 91); +} +.btn-default.active, +.btn-default:active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled.focus, +.btn-default.disabled:focus, +.btn-default.disabled:hover, +.btn-default[disabled].focus, +.btn-default[disabled]:focus, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default.focus, +fieldset[disabled] .btn-default:focus, +fieldset[disabled] .btn-default:hover { + background-color: rgb(24, 26, 27); + border-color: rgb(62, 68, 70); +} +.btn-default .badge { + color: rgb(232, 230, 227); + background-color: rgb(38, 42, 43); +} +.btn-primary { + color: rgb(232, 230, 227); + background-color: rgb(41, 98, 146); + border-color: rgb(42, 100, 150); +} +.btn-primary.focus, +.btn-primary:focus { + color: rgb(232, 230, 227); + background-color: rgb(32, 77, 115); + border-color: rgb(126, 117, 104); +} +.btn-primary:hover { + color: rgb(232, 230, 227); + background-color: rgb(32, 77, 115); + border-color: rgb(46, 110, 165); +} +.btn-primary.active, +.btn-primary:active, +.open > .dropdown-toggle.btn-primary { + color: rgb(232, 230, 227); + background-color: rgb(32, 77, 115); + border-color: rgb(46, 110, 165); +} +.btn-primary.active.focus, +.btn-primary.active:focus, +.btn-primary.active:hover, +.btn-primary:active.focus, +.btn-primary:active:focus, +.btn-primary:active:hover, +.open > .dropdown-toggle.btn-primary.focus, +.open > .dropdown-toggle.btn-primary:focus, +.open > .dropdown-toggle.btn-primary:hover { + color: rgb(232, 230, 227); + background-color: rgb(26, 62, 93); + border-color: rgb(126, 117, 104); +} +.btn-primary.active, +.btn-primary:active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled.focus, +.btn-primary.disabled:focus, +.btn-primary.disabled:hover, +.btn-primary[disabled].focus, +.btn-primary[disabled]:focus, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary.focus, +fieldset[disabled] .btn-primary:focus, +fieldset[disabled] .btn-primary:hover { + background-color: rgb(41, 98, 146); + border-color: rgb(42, 100, 150); +} +.btn-primary .badge { + color: rgb(105, 166, 213); + background-color: rgb(24, 26, 27); +} +.btn-success { + color: rgb(232, 230, 227); + background-color: rgb(77, 133, 58); + border-color: rgb(55, 125, 55); +} +.btn-success.focus, +.btn-success:focus { + color: rgb(232, 230, 227); + background-color: rgb(54, 126, 54); + border-color: rgb(66, 152, 66); +} +.btn-success:hover { + color: rgb(232, 230, 227); + background-color: rgb(54, 126, 54); + border-color: rgb(60, 138, 60); +} +.btn-success.active, +.btn-success:active, +.open > .dropdown-toggle.btn-success { + color: rgb(232, 230, 227); + background-color: rgb(54, 126, 54); + border-color: rgb(60, 138, 60); +} +.btn-success.active.focus, +.btn-success.active:focus, +.btn-success.active:hover, +.btn-success:active.focus, +.btn-success:active:focus, +.btn-success:active:hover, +.open > .dropdown-toggle.btn-success.focus, +.open > .dropdown-toggle.btn-success:focus, +.open > .dropdown-toggle.btn-success:hover { + color: rgb(232, 230, 227); + background-color: rgb(46, 106, 46); + border-color: rgb(66, 152, 66); +} +.btn-success.active, +.btn-success:active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled.focus, +.btn-success.disabled:focus, +.btn-success.disabled:hover, +.btn-success[disabled].focus, +.btn-success[disabled]:focus, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success.focus, +fieldset[disabled] .btn-success:focus, +fieldset[disabled] .btn-success:hover { + background-color: rgb(77, 133, 58); + border-color: rgb(55, 125, 55); +} +.btn-success .badge { + color: rgb(105, 190, 105); + background-color: rgb(24, 26, 27); +} +.btn-info { + color: rgb(232, 230, 227); + background-color: rgb(28, 115, 141); + border-color: rgb(28, 115, 140); +} +.btn-info.focus, +.btn-info:focus { + color: rgb(232, 230, 227); + background-color: rgb(34, 136, 166); + border-color: rgb(35, 141, 172); +} +.btn-info:hover { + color: rgb(232, 230, 227); + background-color: rgb(34, 136, 166); + border-color: rgb(31, 128, 156); +} +.btn-info.active, +.btn-info:active, +.open > .dropdown-toggle.btn-info { + color: rgb(232, 230, 227); + background-color: rgb(34, 136, 166); + border-color: rgb(31, 128, 156); +} +.btn-info.active.focus, +.btn-info.active:focus, +.btn-info.active:hover, +.btn-info:active.focus, +.btn-info:active:focus, +.btn-info:active:hover, +.open > .dropdown-toggle.btn-info.focus, +.open > .dropdown-toggle.btn-info:focus, +.open > .dropdown-toggle.btn-info:hover { + color: rgb(232, 230, 227); + background-color: rgb(30, 123, 150); + border-color: rgb(35, 141, 172); +} +.btn-info.active, +.btn-info:active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled.focus, +.btn-info.disabled:focus, +.btn-info.disabled:hover, +.btn-info[disabled].focus, +.btn-info[disabled]:focus, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info.focus, +fieldset[disabled] .btn-info:focus, +fieldset[disabled] .btn-info:hover { + background-color: rgb(28, 115, 141); + border-color: rgb(28, 115, 140); +} +.btn-info .badge { + color: rgb(98, 195, 223); + background-color: rgb(24, 26, 27); +} +.btn-warning { + color: rgb(232, 230, 227); + background-color: rgb(153, 95, 13); + border-color: rgb(154, 96, 13); +} +.btn-warning.focus, +.btn-warning:focus { + color: rgb(232, 230, 227); + background-color: rgb(181, 113, 15); + border-color: rgb(189, 118, 16); +} +.btn-warning:hover { + color: rgb(232, 230, 227); + background-color: rgb(181, 113, 15); + border-color: rgb(171, 107, 14); +} +.btn-warning.active, +.btn-warning:active, +.open > .dropdown-toggle.btn-warning { + color: rgb(232, 230, 227); + background-color: rgb(181, 113, 15); + border-color: rgb(171, 107, 14); +} +.btn-warning.active.focus, +.btn-warning.active:focus, +.btn-warning.active:hover, +.btn-warning:active.focus, +.btn-warning:active:focus, +.btn-warning:active:hover, +.open > .dropdown-toggle.btn-warning.focus, +.open > .dropdown-toggle.btn-warning:focus, +.open > .dropdown-toggle.btn-warning:hover { + color: rgb(232, 230, 227); + background-color: rgb(170, 106, 14); + border-color: rgb(189, 118, 16); +} +.btn-warning.active, +.btn-warning:active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled.focus, +.btn-warning.disabled:focus, +.btn-warning.disabled:hover, +.btn-warning[disabled].focus, +.btn-warning[disabled]:focus, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning.focus, +fieldset[disabled] .btn-warning:focus, +fieldset[disabled] .btn-warning:hover { + background-color: rgb(153, 95, 13); + border-color: rgb(154, 96, 13); +} +.btn-warning .badge { + color: rgb(241, 176, 84); + background-color: rgb(24, 26, 27); +} +.btn-danger { + color: rgb(232, 230, 227); + background-color: rgb(148, 35, 32); + border-color: rgb(143, 35, 31); +} +.btn-danger.focus, +.btn-danger:focus { + color: rgb(232, 230, 227); + background-color: rgb(161, 38, 35); + border-color: rgb(175, 42, 37); +} +.btn-danger:hover { + color: rgb(232, 230, 227); + background-color: rgb(161, 38, 35); + border-color: rgb(158, 38, 34); +} +.btn-danger.active, +.btn-danger:active, +.open > .dropdown-toggle.btn-danger { + color: rgb(232, 230, 227); + background-color: rgb(161, 38, 35); + border-color: rgb(158, 38, 34); +} +.btn-danger.active.focus, +.btn-danger.active:focus, +.btn-danger.active:hover, +.btn-danger:active.focus, +.btn-danger:active:focus, +.btn-danger:active:hover, +.open > .dropdown-toggle.btn-danger.focus, +.open > .dropdown-toggle.btn-danger:focus, +.open > .dropdown-toggle.btn-danger:hover { + color: rgb(232, 230, 227); + background-color: rgb(138, 33, 30); + border-color: rgb(175, 42, 37); +} +.btn-danger.active, +.btn-danger:active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled.focus, +.btn-danger.disabled:focus, +.btn-danger.disabled:hover, +.btn-danger[disabled].focus, +.btn-danger[disabled]:focus, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger.focus, +fieldset[disabled] .btn-danger:focus, +fieldset[disabled] .btn-danger:hover { + background-color: rgb(148, 35, 32); + border-color: rgb(143, 35, 31); +} +.btn-danger .badge { + color: rgb(219, 94, 90); + background-color: rgb(24, 26, 27); +} +.btn-link { + color: rgb(105, 166, 213); +} +.btn-link, +.btn-link.active, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + box-shadow: none; +} +.btn-link, +.btn-link:active, +.btn-link:focus, +.btn-link:hover { + border-color: transparent; +} +.btn-link:focus, +.btn-link:hover { + color: rgb(141, 187, 223); + text-decoration-color: initial; + background-color: transparent; +} +.btn-link[disabled]:focus, +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:focus, +fieldset[disabled] .btn-link:hover { + color: rgb(157, 148, 136); + text-decoration-color: initial; +} +.caret { + border-top-color: initial; + border-right-color: transparent; + border-left-color: transparent; +} +.dropdown-toggle:focus { + outline-color: initial; +} +.dropdown-menu { + list-style-image: initial; + background-color: rgb(24, 26, 27); + border-color: rgba(140, 130, 115, 0.15); + box-shadow: rgba(0, 0, 0, 0.18) 0px 6px 12px; +} +.dropdown-menu .divider { + background-color: rgb(39, 42, 44); +} +.dropdown-menu > li > a { + color: rgb(200, 195, 188); +} +.dropdown-menu > li > a:focus, +.dropdown-menu > li > a:hover { + color: rgb(208, 204, 198); + text-decoration-color: initial; + background-color: rgb(30, 32, 33); +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:focus, +.dropdown-menu > .active > a:hover { + color: rgb(232, 230, 227); + text-decoration-color: initial; + background-color: rgb(41, 98, 146); + outline-color: initial; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:focus, +.dropdown-menu > .disabled > a:hover { + color: rgb(157, 148, 136); +} +.dropdown-menu > .disabled > a:focus, +.dropdown-menu > .disabled > a:hover { + text-decoration-color: initial; + background-color: transparent; + background-image: none; +} +.open > a { + outline-color: initial; +} +.dropdown-header { + color: rgb(157, 148, 136); +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top-color: initial; + border-bottom-color: initial; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline-color: initial; +} +.btn-group.open .dropdown-toggle { + box-shadow: rgba(0, 0, 0, 0.13) 0px 3px 5px inset; +} +.btn-group.open .dropdown-toggle.btn-link { + box-shadow: none; +} +.input-group-addon { + color: rgb(178, 172, 162); + background-color: rgb(34, 36, 38); + border-color: rgb(62, 68, 70); +} +.input-group-addon:first-child { + border-right-color: initial; +} +.input-group-addon:last-child { + border-left-color: initial; +} +.nav { + list-style-image: initial; +} +.nav > li > a:focus, +.nav > li > a:hover { + text-decoration-color: initial; + background-color: rgb(34, 36, 38); +} +.nav > li.disabled > a { + color: rgb(157, 148, 136); +} +.nav > li.disabled > a:focus, +.nav > li.disabled > a:hover { + color: rgb(157, 148, 136); + text-decoration-color: initial; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:focus, +.nav .open > a:hover { + background-color: rgb(34, 36, 38); + border-color: rgb(40, 96, 145); +} +.nav .nav-divider { + background-color: rgb(39, 42, 44); +} +.nav-tabs { + border-bottom-color: rgb(58, 62, 65); +} +.nav-tabs > li > a { + border-color: transparent; +} +.nav-tabs > li > a:hover { + border-color: rgb(53, 57, 59) rgb(53, 57, 59) rgb(58, 62, 65); +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:focus, +.nav-tabs > li.active > a:hover { + color: rgb(178, 172, 162); + background-color: rgb(24, 26, 27); + border-color: rgb(58, 62, 65) rgb(58, 62, 65) transparent; +} +.nav-tabs.nav-justified { + border-bottom-color: initial; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:focus, +.nav-tabs.nav-justified > .active > a:hover { + border-color: rgb(58, 62, 65); +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom-color: rgb(58, 62, 65); + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:focus, + .nav-tabs.nav-justified > .active > a:hover { + border-bottom-color: rgb(48, 52, 54); + } +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:focus, +.nav-pills > li.active > a:hover { + color: rgb(232, 230, 227); + background-color: rgb(41, 98, 146); +} +.nav-tabs-justified { + border-bottom-color: initial; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:focus, +.nav-tabs-justified > .active > a:hover { + border-color: rgb(58, 62, 65); +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom-color: rgb(58, 62, 65); + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:focus, + .nav-tabs-justified > .active > a:hover { + border-bottom-color: rgb(48, 52, 54); + } +} +.navbar { + border-color: transparent; +} +.navbar-collapse { + border-top-color: transparent; + box-shadow: rgba(24, 26, 27, 0.1) 0px 1px 0px inset; +} +@media (min-width: 768px) { + .navbar-collapse { + border-top-color: initial; + box-shadow: none; + } +} +.navbar-brand:focus, +.navbar-brand:hover { + text-decoration-color: initial; +} +.navbar-toggle { + background-color: transparent; + background-image: none; + border-color: transparent; +} +.navbar-toggle:focus { + outline-color: initial; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + background-color: transparent; + border-color: initial; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a:focus, + .navbar-nav .open .dropdown-menu > li > a:hover { + background-image: none; + } +} +.navbar-form { + border-top-color: transparent; + border-bottom-color: transparent; + box-shadow: rgba(24, 26, 27, 0.1) 0px 1px 0px inset, + rgba(24, 26, 27, 0.1) 0px 1px 0px; +} +@media (min-width: 768px) { + .navbar-form { + border-color: initial; + box-shadow: none; + } +} +.navbar-default { + background-color: rgb(28, 30, 31); + border-color: rgb(55, 59, 62); +} +.navbar-default .navbar-brand { + color: rgb(157, 148, 136); +} +.navbar-default .navbar-brand:focus, +.navbar-default .navbar-brand:hover { + color: rgb(173, 165, 155); + background-color: transparent; +} +.navbar-default .navbar-text { + color: rgb(157, 148, 136); +} +.navbar-default .navbar-nav > li > a { + color: rgb(157, 148, 136); +} +.navbar-default .navbar-nav > li > a:focus, +.navbar-default .navbar-nav > li > a:hover { + color: rgb(200, 195, 188); + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:focus, +.navbar-default .navbar-nav > .active > a:hover { + color: rgb(178, 172, 162); + background-color: rgb(38, 41, 42); +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:focus, +.navbar-default .navbar-nav > .disabled > a:hover { + color: rgb(200, 195, 188); + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: rgb(58, 62, 65); +} +.navbar-default .navbar-toggle:focus, +.navbar-default .navbar-toggle:hover { + background-color: rgb(43, 47, 49); +} +.navbar-default .navbar-toggle .icon-bar { + background-color: rgb(91, 99, 103); +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: rgb(55, 59, 62); +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:focus, +.navbar-default .navbar-nav > .open > a:hover { + color: rgb(178, 172, 162); + background-color: rgb(38, 41, 42); +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: rgb(157, 148, 136); + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover { + color: rgb(200, 195, 188); + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover { + color: rgb(178, 172, 162); + background-color: rgb(38, 41, 42); + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover { + color: rgb(200, 195, 188); + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: rgb(157, 148, 136); +} +.navbar-default .navbar-link:hover { + color: rgb(200, 195, 188); +} +.navbar-default .btn-link { + color: rgb(157, 148, 136); +} +.navbar-default .btn-link:focus, +.navbar-default .btn-link:hover { + color: rgb(200, 195, 188); +} +.navbar-default .btn-link[disabled]:focus, +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:focus, +fieldset[disabled] .navbar-default .btn-link:hover { + color: rgb(200, 195, 188); +} +.navbar-inverse { + background-color: rgb(26, 28, 29); + border-color: rgb(137, 128, 113); +} +.navbar-inverse .navbar-brand { + color: rgb(170, 163, 152); +} +.navbar-inverse .navbar-brand:focus, +.navbar-inverse .navbar-brand:hover { + color: rgb(232, 230, 227); + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: rgb(170, 163, 152); +} +.navbar-inverse .navbar-nav > li > a { + color: rgb(170, 163, 152); +} +.navbar-inverse .navbar-nav > li > a:focus, +.navbar-inverse .navbar-nav > li > a:hover { + color: rgb(232, 230, 227); + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:focus, +.navbar-inverse .navbar-nav > .active > a:hover { + color: rgb(232, 230, 227); + background-color: rgb(6, 7, 7); +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:focus, +.navbar-inverse .navbar-nav > .disabled > a:hover { + color: rgb(189, 183, 175); + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: rgb(123, 114, 101); +} +.navbar-inverse .navbar-toggle:focus, +.navbar-inverse .navbar-toggle:hover { + background-color: rgb(38, 42, 43); +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: rgb(24, 26, 27); +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: rgb(135, 125, 111); +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:focus, +.navbar-inverse .navbar-nav > .open > a:hover { + color: rgb(232, 230, 227); + background-color: rgb(6, 7, 7); +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: rgb(137, 128, 113); + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: rgb(6, 7, 7); + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: rgb(170, 163, 152); + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover { + color: rgb(232, 230, 227); + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover { + color: rgb(232, 230, 227); + background-color: rgb(6, 7, 7); + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover { + color: rgb(189, 183, 175); + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: rgb(170, 163, 152); +} +.navbar-inverse .navbar-link:hover { + color: rgb(232, 230, 227); +} +.navbar-inverse .btn-link { + color: rgb(170, 163, 152); +} +.navbar-inverse .btn-link:focus, +.navbar-inverse .btn-link:hover { + color: rgb(232, 230, 227); +} +.navbar-inverse .btn-link[disabled]:focus, +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:focus, +fieldset[disabled] .navbar-inverse .btn-link:hover { + color: rgb(189, 183, 175); +} +.breadcrumb { + list-style-image: initial; + background-color: rgb(30, 32, 33); +} +.breadcrumb > li + li::before { + color: rgb(200, 195, 188); +} +.breadcrumb > .active { + color: rgb(157, 148, 136); +} +.pagination > li > a, +.pagination > li > span { + color: rgb(105, 166, 213); + text-decoration-color: initial; + background-color: rgb(24, 26, 27); + border-color: rgb(58, 62, 65); +} +.pagination > li > a:focus, +.pagination > li > a:hover, +.pagination > li > span:focus, +.pagination > li > span:hover { + color: rgb(141, 187, 223); + background-color: rgb(34, 36, 38); + border-color: rgb(58, 62, 65); +} +.pagination > .active > a, +.pagination > .active > a:focus, +.pagination > .active > a:hover, +.pagination > .active > span, +.pagination > .active > span:focus, +.pagination > .active > span:hover { + color: rgb(232, 230, 227); + background-color: rgb(41, 98, 146); + border-color: rgb(40, 96, 145); +} +.pagination > .disabled > a, +.pagination > .disabled > a:focus, +.pagination > .disabled > a:hover, +.pagination > .disabled > span, +.pagination > .disabled > span:focus, +.pagination > .disabled > span:hover { + color: rgb(157, 148, 136); + background-color: rgb(24, 26, 27); + border-color: rgb(58, 62, 65); +} +.pager { + list-style-image: initial; +} +.pager li > a, +.pager li > span { + background-color: rgb(24, 26, 27); + border-color: rgb(58, 62, 65); +} +.pager li > a:focus, +.pager li > a:hover { + text-decoration-color: initial; + background-color: rgb(34, 36, 38); +} +.pager .disabled > a, +.pager .disabled > a:focus, +.pager .disabled > a:hover, +.pager .disabled > span { + color: rgb(157, 148, 136); + background-color: rgb(24, 26, 27); +} +.label { + color: rgb(232, 230, 227); +} +a.label:focus, +a.label:hover { + color: rgb(232, 230, 227); + text-decoration-color: initial; +} +.label-default { + background-color: rgb(90, 97, 101); +} +.label-default[href]:focus, +.label-default[href]:hover { + background-color: rgb(71, 77, 80); +} +.label-primary { + background-color: rgb(41, 98, 146); +} +.label-primary[href]:focus, +.label-primary[href]:hover { + background-color: rgb(32, 77, 115); +} +.label-success { + background-color: rgb(77, 133, 58); +} +.label-success[href]:focus, +.label-success[href]:hover { + background-color: rgb(54, 126, 54); +} +.label-info { + background-color: rgb(28, 115, 141); +} +.label-info[href]:focus, +.label-info[href]:hover { + background-color: rgb(34, 136, 166); +} +.label-warning { + background-color: rgb(153, 95, 13); +} +.label-warning[href]:focus, +.label-warning[href]:hover { + background-color: rgb(181, 113, 15); +} +.label-danger { + background-color: rgb(148, 35, 32); +} +.label-danger[href]:focus, +.label-danger[href]:hover { + background-color: rgb(161, 38, 35); +} +.badge { + color: rgb(232, 230, 227); + background-color: rgb(90, 97, 101); +} +a.badge:focus, +a.badge:hover { + color: rgb(232, 230, 227); + text-decoration-color: initial; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: rgb(105, 166, 213); + background-color: rgb(24, 26, 27); +} +.jumbotron { + color: inherit; + background-color: rgb(34, 36, 38); +} +.jumbotron .h1, +.jumbotron h1 { + color: inherit; +} +.jumbotron > hr { + border-top-color: rgb(60, 65, 67); +} +.thumbnail { + background-color: rgb(24, 26, 27); + border-color: rgb(58, 62, 65); +} +a.thumbnail.active, +a.thumbnail:focus, +a.thumbnail:hover { + border-color: rgb(40, 96, 145); +} +.thumbnail .caption { + color: rgb(200, 195, 188); +} +.alert { + border-color: transparent; +} +.alert h4 { + color: inherit; +} +.alert-dismissable .close, +.alert-dismissible .close { + color: inherit; +} +.alert-success { + color: rgb(139, 196, 140); + background-color: rgb(41, 60, 23); + border-color: rgb(60, 91, 35); +} +.alert-success hr { + border-top-color: rgb(65, 97, 37); +} +.alert-success .alert-link { + color: rgb(162, 208, 164); +} +.alert-info { + color: rgb(117, 178, 208); + background-color: rgb(14, 48, 65); + border-color: rgb(22, 90, 104); +} +.alert-info hr { + border-top-color: rgb(24, 97, 111); +} +.alert-info .alert-link { + color: rgb(144, 192, 217); +} +.alert-warning { + color: rgb(198, 171, 123); + background-color: rgb(63, 54, 7); + border-color: rgb(108, 76, 11); +} +.alert-warning hr { + border-top-color: rgb(114, 80, 12); +} +.alert-warning .alert-link { + color: rgb(209, 187, 148); +} +.alert-danger { + color: rgb(194, 102, 100); + background-color: rgb(56, 22, 22); + border-color: rgb(89, 35, 43); +} +.alert-danger hr { + border-top-color: rgb(95, 36, 46); +} +.alert-danger .alert-link { + color: rgb(204, 127, 126); +} +.progress { + background-color: rgb(30, 32, 33); + box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px inset; +} +.progress-bar { + color: rgb(232, 230, 227); + background-color: rgb(41, 98, 146); + box-shadow: rgba(0, 0, 0, 0.15) 0px -1px 0px inset; +} +.progress-bar-striped, +.progress-striped .progress-bar { + background-image: linear-gradient(45deg, + rgba(24, 26, 27, 0.15) 25%, + rgba(0, 0, 0, 0) 25%, + rgba(0, 0, 0, 0) 50%, + rgba(24, 26, 27, 0.15) 50%, + rgba(24, 26, 27, 0.15) 75%, + rgba(0, 0, 0, 0) 75%, + rgba(0, 0, 0, 0)); +} +.progress-bar-success { + background-color: rgb(77, 133, 58); +} +.progress-striped .progress-bar-success { + background-image: linear-gradient(45deg, + rgba(24, 26, 27, 0.15) 25%, + rgba(0, 0, 0, 0) 25%, + rgba(0, 0, 0, 0) 50%, + rgba(24, 26, 27, 0.15) 50%, + rgba(24, 26, 27, 0.15) 75%, + rgba(0, 0, 0, 0) 75%, + rgba(0, 0, 0, 0)); +} +.progress-bar-info { + background-color: rgb(28, 115, 141); +} +.progress-striped .progress-bar-info { + background-image: linear-gradient(45deg, + rgba(24, 26, 27, 0.15) 25%, + rgba(0, 0, 0, 0) 25%, + rgba(0, 0, 0, 0) 50%, + rgba(24, 26, 27, 0.15) 50%, + rgba(24, 26, 27, 0.15) 75%, + rgba(0, 0, 0, 0) 75%, + rgba(0, 0, 0, 0)); +} +.progress-bar-warning { + background-color: rgb(153, 95, 13); +} +.progress-striped .progress-bar-warning { + background-image: linear-gradient(45deg, + rgba(24, 26, 27, 0.15) 25%, + rgba(0, 0, 0, 0) 25%, + rgba(0, 0, 0, 0) 50%, + rgba(24, 26, 27, 0.15) 50%, + rgba(24, 26, 27, 0.15) 75%, + rgba(0, 0, 0, 0) 75%, + rgba(0, 0, 0, 0)); +} +.progress-bar-danger { + background-color: rgb(148, 35, 32); +} +.progress-striped .progress-bar-danger { + background-image: linear-gradient(45deg, + rgba(24, 26, 27, 0.15) 25%, + rgba(0, 0, 0, 0) 25%, + rgba(0, 0, 0, 0) 50%, + rgba(24, 26, 27, 0.15) 50%, + rgba(24, 26, 27, 0.15) 75%, + rgba(0, 0, 0, 0) 75%, + rgba(0, 0, 0, 0)); +} +.media-list { + list-style-image: initial; +} +.list-group-item { + background-color: rgb(24, 26, 27); + border-color: rgb(58, 62, 65); +} +a.list-group-item, +button.list-group-item { + color: rgb(178, 172, 162); +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: rgb(200, 195, 188); +} +a.list-group-item:focus, +a.list-group-item:hover, +button.list-group-item:focus, +button.list-group-item:hover { + color: rgb(178, 172, 162); + text-decoration-color: initial; + background-color: rgb(30, 32, 33); +} +.list-group-item.disabled, +.list-group-item.disabled:focus, +.list-group-item.disabled:hover { + color: rgb(157, 148, 136); + background-color: rgb(34, 36, 38); +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text { + color: rgb(157, 148, 136); +} +.list-group-item.active, +.list-group-item.active:focus, +.list-group-item.active:hover { + color: rgb(232, 230, 227); + background-color: rgb(41, 98, 146); + border-color: rgb(40, 96, 145); +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:focus .list-group-item-text, +.list-group-item.active:hover .list-group-item-text { + color: rgb(176, 208, 232); +} +.list-group-item-success { + color: rgb(139, 196, 140); + background-color: rgb(41, 60, 23); +} +a.list-group-item-success, +button.list-group-item-success { + color: rgb(139, 196, 140); +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:focus, +a.list-group-item-success:hover, +button.list-group-item-success:focus, +button.list-group-item-success:hover { + color: rgb(139, 196, 140); + background-color: rgb(48, 71, 27); +} +a.list-group-item-success.active, +a.list-group-item-success.active:focus, +a.list-group-item-success.active:hover, +button.list-group-item-success.active, +button.list-group-item-success.active:focus, +button.list-group-item-success.active:hover { + color: rgb(232, 230, 227); + background-color: rgb(48, 94, 49); + border-color: rgb(68, 134, 69); +} +.list-group-item-info { + color: rgb(117, 178, 208); + background-color: rgb(14, 48, 65); +} +a.list-group-item-info, +button.list-group-item-info { + color: rgb(117, 178, 208); +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:focus, +a.list-group-item-info:hover, +button.list-group-item-info:focus, +button.list-group-item-info:hover { + color: rgb(117, 178, 208); + background-color: rgb(44, 48, 50); +} +a.list-group-item-info.active, +a.list-group-item-info.active:focus, +a.list-group-item-info.active:hover, +button.list-group-item-info.active, +button.list-group-item-info.active:focus, +button.list-group-item-info.active:hover { + color: rgb(232, 230, 227); + background-color: rgb(39, 90, 114); + border-color: rgb(50, 115, 147); +} +.list-group-item-warning { + color: rgb(198, 171, 123); + background-color: rgb(63, 54, 7); +} +a.list-group-item-warning, +button.list-group-item-warning { + color: rgb(198, 171, 123); +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:focus, +a.list-group-item-warning:hover, +button.list-group-item-warning:focus, +button.list-group-item-warning:hover { + color: rgb(198, 171, 123); + background-color: rgb(77, 65, 8); +} +a.list-group-item-warning.active, +a.list-group-item-warning.active:focus, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active, +button.list-group-item-warning.active:focus, +button.list-group-item-warning.active:hover { + color: rgb(232, 230, 227); + background-color: rgb(110, 87, 47); + border-color: rgb(137, 108, 59); +} +.list-group-item-danger { + color: rgb(194, 102, 100); + background-color: rgb(56, 22, 22); +} +a.list-group-item-danger, +button.list-group-item-danger { + color: rgb(194, 102, 100); +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:focus, +a.list-group-item-danger:hover, +button.list-group-item-danger:focus, +button.list-group-item-danger:hover { + color: rgb(194, 102, 100); + background-color: rgb(67, 26, 26); +} +a.list-group-item-danger.active, +a.list-group-item-danger.active:focus, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active, +button.list-group-item-danger.active:focus, +button.list-group-item-danger.active:hover { + color: rgb(232, 230, 227); + background-color: rgb(135, 54, 53); + border-color: rgb(133, 53, 52); +} +.panel { + background-color: rgb(24, 26, 27); + border-color: transparent; + box-shadow: rgba(0, 0, 0, 0.05) 0px 1px 1px; +} +.panel-heading { + border-bottom-color: transparent; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + color: inherit; +} +.panel-title > .small, +.panel-title > .small > a, +.panel-title > a, +.panel-title > small, +.panel-title > small > a { + color: inherit; +} +.panel-footer { + background-color: rgb(30, 32, 33); + border-top-color: rgb(58, 62, 65); +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top-color: initial; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom-color: initial; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top-color: rgb(58, 62, 65); +} +.panel > .table > tbody:first-child > tr:first-child td, +.panel > .table > tbody:first-child > tr:first-child th { + border-top-color: initial; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border-color: initial; +} +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child { + border-left-color: initial; +} +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child { + border-right-color: initial; +} +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th { + border-bottom-color: initial; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom-color: initial; +} +.panel > .table-responsive { + border-color: initial; +} +.panel-group .panel-heading { + border-bottom-color: initial; +} +.panel-group .panel-heading + .panel-collapse > .list-group, +.panel-group .panel-heading + .panel-collapse > .panel-body { + border-top-color: rgb(58, 62, 65); +} +.panel-group .panel-footer { + border-top-color: initial; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom-color: rgb(58, 62, 65); +} +.panel-default { + border-color: rgb(58, 62, 65); +} +.panel-default > .panel-heading { + color: rgb(200, 195, 188); + background-color: rgb(30, 32, 33); + border-color: rgb(58, 62, 65); +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: rgb(58, 62, 65); +} +.panel-default > .panel-heading .badge { + color: rgb(226, 223, 219); + background-color: rgb(38, 42, 43); +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: rgb(58, 62, 65); +} +.panel-primary { + border-color: rgb(40, 96, 145); +} +.panel-primary > .panel-heading { + color: rgb(232, 230, 227); + background-color: rgb(41, 98, 146); + border-color: rgb(40, 96, 145); +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: rgb(40, 96, 145); +} +.panel-primary > .panel-heading .badge { + color: rgb(105, 166, 213); + background-color: rgb(24, 26, 27); +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: rgb(40, 96, 145); +} +.panel-success { + border-color: rgb(60, 91, 35); +} +.panel-success > .panel-heading { + color: rgb(139, 196, 140); + background-color: rgb(41, 60, 23); + border-color: rgb(60, 91, 35); +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: rgb(60, 91, 35); +} +.panel-success > .panel-heading .badge { + color: rgb(202, 230, 191); + background-color: rgb(48, 94, 49); +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: rgb(60, 91, 35); +} +.panel-info { + border-color: rgb(22, 90, 104); +} +.panel-info > .panel-heading { + color: rgb(117, 178, 208); + background-color: rgb(14, 48, 65); + border-color: rgb(22, 90, 104); +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: rgb(22, 90, 104); +} +.panel-info > .panel-heading .badge { + color: rgb(186, 222, 241); + background-color: rgb(39, 90, 114); +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: rgb(22, 90, 104); +} +.panel-warning { + border-color: rgb(108, 76, 11); +} +.panel-warning > .panel-heading { + color: rgb(198, 171, 123); + background-color: rgb(63, 54, 7); + border-color: rgb(108, 76, 11); +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: rgb(108, 76, 11); +} +.panel-warning > .panel-heading .badge { + color: rgb(248, 239, 189); + background-color: rgb(110, 87, 47); +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: rgb(108, 76, 11); +} +.panel-danger { + border-color: rgb(89, 35, 43); +} +.panel-danger > .panel-heading { + color: rgb(194, 102, 100); + background-color: rgb(56, 22, 22); + border-color: rgb(89, 35, 43); +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: rgb(89, 35, 43); +} +.panel-danger > .panel-heading .badge { + color: rgb(231, 195, 195); + background-color: rgb(135, 54, 53); +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: rgb(89, 35, 43); +} +.embed-responsive .embed-responsive-item, +.embed-responsive embed, +.embed-responsive iframe, +.embed-responsive object, +.embed-responsive video { + border-color: initial; +} +.well { + background-color: rgb(30, 32, 33); + border-color: rgb(56, 61, 63); + box-shadow: rgba(0, 0, 0, 0.05) 0px 1px 1px inset; +} +.well blockquote { + border-color: rgba(140, 130, 115, 0.15); +} +.close { + color: rgb(232, 230, 227); + text-shadow: rgb(24, 26, 27) 0px 1px 0px; +} +.close:focus, +.close:hover { + color: rgb(232, 230, 227); + text-decoration-color: initial; +} +button.close { + background-image: initial; + background-color: initial; + border-color: initial; +} +.modal { + outline-color: initial; +} +.modal-content { + background-color: rgb(24, 26, 27); + border-color: rgba(140, 130, 115, 0.2); + outline-color: initial; + box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 9px; +} +.modal-backdrop { + background-color: rgb(0, 0, 0); +} +.modal-header { + border-bottom-color: rgb(55, 60, 62); +} +.modal-footer { + border-top-color: rgb(55, 60, 62); +} +@media (min-width: 768px) { + .modal-content { + box-shadow: rgba(0, 0, 0, 0.5) 0px 5px 15px; + } +} +.tooltip { + text-decoration-color: initial; + text-shadow: none; +} +.tooltip-inner { + color: rgb(232, 230, 227); + background-color: rgb(0, 0, 0); +} +.tooltip-arrow { + border-color: transparent; +} +.tooltip.top .tooltip-arrow { + border-top-color: rgb(140, 130, 115); +} +.tooltip.top-left .tooltip-arrow { + border-top-color: rgb(140, 130, 115); +} +.tooltip.top-right .tooltip-arrow { + border-top-color: rgb(140, 130, 115); +} +.tooltip.right .tooltip-arrow { + border-right-color: rgb(140, 130, 115); +} +.tooltip.left .tooltip-arrow { + border-left-color: rgb(140, 130, 115); +} +.tooltip.bottom .tooltip-arrow { + border-bottom-color: rgb(140, 130, 115); +} +.tooltip.bottom-left .tooltip-arrow { + border-bottom-color: rgb(140, 130, 115); +} +.tooltip.bottom-right .tooltip-arrow { + border-bottom-color: rgb(140, 130, 115); +} +.popover { + text-decoration-color: initial; + text-shadow: none; + background-color: rgb(24, 26, 27); + border-color: rgba(140, 130, 115, 0.2); + box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 10px; +} +.popover-title { + background-color: rgb(29, 31, 32); + border-bottom-color: rgb(54, 58, 60); +} +.popover > .arrow, +.popover > .arrow::after { + border-color: transparent; +} +.popover.top > .arrow { + border-top-color: rgba(140, 130, 115, 0.25); +} +.popover.top > .arrow::after { + border-top-color: rgb(48, 52, 54); +} +.popover.right > .arrow { + border-right-color: rgba(140, 130, 115, 0.25); +} +.popover.right > .arrow::after { + border-right-color: rgb(48, 52, 54); +} +.popover.bottom > .arrow { + border-bottom-color: rgba(140, 130, 115, 0.25); +} +.popover.bottom > .arrow::after { + border-bottom-color: rgb(48, 52, 54); +} +.popover.left > .arrow { + border-left-color: rgba(140, 130, 115, 0.25); +} +.popover.left > .arrow::after { + border-left-color: rgb(48, 52, 54); +} +.carousel-control { + color: rgb(232, 230, 227); + text-shadow: rgba(0, 0, 0, 0.6) 0px 1px 2px; + background-color: rgba(0, 0, 0, 0); +} +.carousel-control.left { + background-image: linear-gradient(to right, + rgba(0, 0, 0, 0.5) 0px, + rgba(0, 0, 0, 0) 100%); +} +.carousel-control.right { + background-image: linear-gradient(to right, + rgba(0, 0, 0, 0) 0px, + rgba(0, 0, 0, 0.5) 100%); +} +.carousel-control:focus, +.carousel-control:hover { + color: rgb(232, 230, 227); + text-decoration-color: initial; + outline-color: initial; +} +.carousel-indicators { + list-style-image: initial; +} +.carousel-indicators li { + background-color: rgba(0, 0, 0, 0); + border-color: rgb(48, 52, 54); +} +.carousel-indicators .active { + background-color: rgb(24, 26, 27); +} +.carousel-caption { + color: rgb(232, 230, 227); + text-shadow: rgba(0, 0, 0, 0.6) 0px 1px 2px; +} +.carousel-caption .btn { + text-shadow: none; +} +.text-hide { + color: transparent; + text-shadow: none; + background-color: transparent; + border-color: initial; +} +.bootstrap-table .fixed-table-container.fixed-height:not(.has-footer) { + border-bottom-color: rgb(56, 61, 63); +} +.bootstrap-table .fixed-table-container.fixed-height .fixed-table-border { + border-left-color: rgb(56, 61, 63); + border-right-color: rgb(56, 61, 63); +} +.bootstrap-table .fixed-table-container.fixed-height .table thead th { + border-bottom-color: rgb(56, 61, 63); +} +.bootstrap-table .fixed-table-container.fixed-height .table-dark thead th { + border-bottom-color: rgb(122, 113, 100); +} +.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading { + background-image: initial; + background-color: rgb(24, 26, 27); +} +.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot, +.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after, +.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::before { + background-image: initial; + background-color: rgb(28, 30, 31); +} +.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark { + background-image: initial; + background-color: rgb(28, 30, 31); +} +.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-dot, +.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::after, +.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::before { + background-image: initial; + background-color: rgb(24, 26, 27); +} +.bootstrap-table .fixed-table-container .table thead th:focus { + outline-color: transparent; +} +.bootstrap-table .fixed-table-container .table thead th .both { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC"); +} +.bootstrap-table .fixed-table-container .table thead th .asc { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg=="); +} +.bootstrap-table .fixed-table-container .table thead th .desc { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= "); +} +.bootstrap-table .fixed-table-container .table tbody tr.selected td { + background-color: rgba(0, 0, 0, 0.07); +} +.bootstrap-table .fixed-table-pagination > .pagination ul.pagination li.page-intermediate a { + color: rgb(197, 192, 185); +} +.bootstrap-table.fullscreen { + background-image: initial; + background-color: rgb(24, 26, 27); +} +.select2-container .select2-search--inline .select2-search__field { + border-color: initial; +} +.select2-dropdown { + background-color: rgb(24, 26, 27); + border-color: rgb(72, 78, 81); +} +.select2-results__options { + list-style-image: initial; +} +.select2-container--open .select2-dropdown--above { + border-bottom-color: initial; +} +.select2-container--open .select2-dropdown--below { + border-top-color: initial; +} +.select2-close-mask { + border-color: initial; + background-color: rgb(24, 26, 27); +} +.select2-hidden-accessible { + border-color: initial !important; +} +.select2-container--default .select2-selection--single { + background-color: rgb(24, 26, 27); + border-color: rgb(72, 78, 81); +} +.select2-container--default .select2-selection--single .select2-selection__rendered { + color: rgb(189, 183, 175); +} +.select2-container--default .select2-selection--single .select2-selection__placeholder { + color: rgb(168, 160, 149); +} +.select2-container--default .select2-selection--single .select2-selection__arrow b { + border-color: rgb(82, 88, 92) transparent transparent; +} +.select2-container--default.select2-container--disabled .select2-selection--single { + background-color: rgb(34, 36, 38); +} +.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent rgb(82, 88, 92); +} +.select2-container--default .select2-selection--multiple { + background-color: rgb(24, 26, 27); + border-color: rgb(72, 78, 81); +} +.select2-container--default .select2-selection--multiple .select2-selection__rendered { + list-style-image: initial; +} +.select2-container--default .select2-selection--multiple .select2-selection__rendered li { + list-style-image: initial; +} +.select2-container--default .select2-selection--multiple .select2-selection__placeholder { + color: rgb(168, 160, 149); +} +.select2-container--default .select2-selection--multiple .select2-selection__choice { + background-color: rgb(39, 43, 44); + border-color: rgb(72, 78, 81); +} +.select2-container--default .select2-selection--multiple .select2-selection__choice__remove { + color: rgb(168, 160, 149); +} +.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { + color: rgb(200, 195, 188); +} +.select2-container--default.select2-container--focus .select2-selection--multiple { + border-color: rgb(140, 130, 115); + outline-color: initial; +} +.select2-container--default.select2-container--disabled .select2-selection--multiple { + background-color: rgb(34, 36, 38); +} +.select2-container--default .select2-search--dropdown .select2-search__field { + border-color: rgb(72, 78, 81); +} +.select2-container--default .select2-search--inline .select2-search__field { + background-image: initial; background-color: transparent; border-color: initial; outline-color: initial; box-shadow: none; +} +.select2-container--default .select2-results__option[aria-disabled="true"] { + color: rgb(168, 160, 149); +} +.select2-container--default .select2-results__option[aria-selected="true"] { + background-color: rgb(43, 47, 49); +} +.select2-container--default .select2-results__option--highlighted[aria-selected] { + background-color: rgb(4, 60, 150); + color: rgb(232, 230, 227); +} +.select2-container--classic .select2-selection--single { + background-color: rgb(29, 31, 32); + border-color: rgb(72, 78, 81); + outline-color: initial; + background-image: linear-gradient(rgb(24, 26, 27) 50%, + rgb(34, 36, 38) 100%); +} +.select2-container--classic .select2-selection--single:focus { + border-color: rgb(4, 60, 150); +} +.select2-container--classic .select2-selection--single .select2-selection__rendered { + color: rgb(189, 183, 175); +} +.select2-container--classic .select2-selection--single .select2-selection__placeholder { + color: rgb(168, 160, 149); +} +.select2-container--classic .select2-selection--single .select2-selection__arrow { + background-color: rgb(43, 47, 49); + border-top-color: initial; + border-right-color: initial; + border-bottom-color: initial; + border-left-color: rgb(72, 78, 81); + background-image: linear-gradient(rgb(34, 36, 38) 50%, + rgb(53, 57, 59) 100%); +} +.select2-container--classic .select2-selection--single .select2-selection__arrow b { + border-color: rgb(82, 88, 92) transparent transparent; +} +.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { + border-top-color: initial; + border-bottom-color: initial; + border-left-color: initial; + border-right-color: rgb(72, 78, 81); +} +.select2-container--classic.select2-container--open .select2-selection--single { + border-color: rgb(4, 60, 150); +} +.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { + background-image: initial; + background-color: transparent; + border-color: initial; +} +.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent rgb(82, 88, 92); +} +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { + border-top-color: initial; + background-image: linear-gradient(rgb(24, 26, 27) 0%, + rgb(34, 36, 38) 50%); +} +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { + border-bottom-color: initial; + background-image: linear-gradient(rgb(34, 36, 38) 50%, + rgb(24, 26, 27) 100%); +} +.select2-container--classic .select2-selection--multiple { + background-color: rgb(24, 26, 27); + border-color: rgb(72, 78, 81); + outline-color: initial; +} +.select2-container--classic .select2-selection--multiple:focus { + border-color: rgb(4, 60, 150); +} +.select2-container--classic .select2-selection--multiple .select2-selection__rendered { + list-style-image: initial; +} +.select2-container--classic .select2-selection--multiple .select2-selection__choice { + background-color: rgb(39, 43, 44); + border-color: rgb(72, 78, 81); +} +.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { + color: rgb(157, 148, 136); +} +.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { + color: rgb(178, 172, 162); +} +.select2-container--classic.select2-container--open .select2-selection--multiple { + border-color: rgb(4, 60, 150); +} +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { + border-top-color: initial; +} +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom-color: initial; +} +.select2-container--classic .select2-search--dropdown .select2-search__field { + border-color: rgb(72, 78, 81); + outline-color: initial; +} +.select2-container--classic .select2-search--inline .select2-search__field { + outline-color: initial; + box-shadow: none; +} +.select2-container--classic .select2-dropdown { + background-color: rgb(24, 26, 27); border-color: transparent; +} +.select2-container--classic .select2-dropdown--above { + border-bottom-color: initial; +} +.select2-container--classic .select2-dropdown--below { + border-top-color: initial; +} +.select2-container--classic .select2-results__option[aria-disabled="true"] { + color: rgb(152, 143, 129); +} +.select2-container--classic .select2-results__option--highlighted[aria-selected] { + background-color: rgb(33, 82, 162); + color: rgb(232, 230, 227); +} +.select2-container--classic.select2-container--open .select2-dropdown { + border-color: rgb(4, 60, 150); +} +.toggle-on { + border-color: initial; +} +.toggle-off { + border-color: initial; +} +.markdownx .row { + border-color: rgb(31, 31, 92); +} +.markdownx-editor { + border-color: rgb(31, 31, 92); +} +.markdownx-preview { + border-color: rgb(31, 31, 92); +} +.progress { + background-image: initial; + background-color: rgb(32, 34, 36); +} +.progress-bar { + background-image: initial; + background-color: rgb(34, 128, 34); +} +.progress-bar-under { + background-image: initial; + background-color: rgb(169, 113, 14); +} +.progress-bar-over { + background-image: initial; + background-color: rgb(41, 98, 146); +} +.progress-value { + color: rgb(200, 195, 188); +} +.navbar-barcode-li { + border-left-color: initial; + border-right-color: initial; +} +.navbar-nav > li { + border-color: rgb(53, 57, 59); +} +.starred-part { + color: rgb(255, 194, 26); +} +.red-cell { + background-color: rgb(121, 18, 18); +} +.part-price { + color: rgb(37, 246, 47); +} +.icon-red { + color: rgb(208, 97, 97); +} +.icon-green { + color: rgb(87, 195, 87); +} +.icon-blue { + color: rgb(97, 137, 208); +} +.icon-yellow { + color: rgb(224, 224, 68); +} +.label-large { + border-color: initial; + background-image: none; + background-color: initial; +} +.label-large-red { + color: rgb(228, 97, 94); + border-color: rgb(138, 25, 23); +} +.label-red { + background-image: initial; + background-color: rgb(145, 27, 24); +} +.label-large-blue { + color: rgb(85, 160, 196); + border-color: rgb(46, 104, 133); +} +.label-blue { + background-image: initial; + background-color: rgb(52, 118, 151); +} +.label-large-green { + color: rgb(101, 183, 102); + border-color: rgb(58, 122, 58); +} +.label-green { + background-image: initial; + background-color: rgb(64, 136, 65); +} +.label-large-grey { + color: rgb(178, 172, 162); + border-color: rgb(72, 78, 81); +} +.label-grey { + background-image: initial; + background-color: rgb(72, 78, 81); +} +.label-large-yellow { + color: rgb(253, 203, 55); + border-color: rgb(165, 124, 2); +} +.label-yellow { + background-image: initial; + background-color: rgb(178, 134, 2); +} +.stock-sub-group td { + background-color: rgb(25, 45, 45); +} +.detail-icon .glyphicon { + color: rgb(148, 208, 146); +} +.basecurrency { + color: rgb(205, 201, 194); +} +.rowvalid { + color: rgb(205, 201, 194); +} +.rowinvalid { + color: rgb(255, 85, 85); +} +.filter-list { + background-image: initial; + background-color: rgb(34, 36, 38); + border-color: rgb(53, 57, 59); +} +.filter-list .close:hover { + background-image: initial; + background-color: rgb(62, 68, 70); +} +.filter-tag { + border-color: rgb(72, 78, 81); + background-image: initial; + background-color: rgb(34, 36, 38); +} +.filter-tag:hover { + background-image: initial; + background-color: rgb(43, 47, 49); +} +.hover-img-thumb { + background-image: initial; + background-color: rgb(34, 36, 38); + border-color: rgb(31, 31, 92); +} +.hover-img-large { + background-image: initial; + background-color: rgb(34, 36, 38); + border-color: rgb(112, 104, 92); +} +.dragover { + background-color: rgb(68, 68, 136); + border-color: rgb(134, 125, 110); +} +.table-img-grid .grid-image { + background-image: initial; + background-color: rgb(34, 36, 38); +} +.badge { + background-color: rgb(90, 97, 101); + color: rgb(232, 230, 227); +} +.badge-alert { + background-color: rgb(173, 0, 0); +} +.part-thumb { + border-color: rgb(72, 78, 81); +} +input[type="submit"] { + color: rgb(200, 195, 188); + background-color: rgb(38, 41, 43); + border-color: rgb(71, 77, 80); +} +.modal .btn-secondary { + background-color: rgb(75, 100, 108); +} +.sidenav { + background-color: rgb(24, 26, 27); +} +.help-inline { + color: rgb(238, 90, 90); +} +.btn-remove { + color: rgb(238, 90, 90); +} +.btn-create { + color: rgb(90, 238, 90); +} +.btn-edit { + color: rgb(90, 144, 238); +} +.panel-heading { + background-color: rgb(27, 29, 30); +} +.warning-msg { + color: rgb(255, 37, 37); +} +.part-allocation { + border-color: rgb(62, 68, 70); +} +.part-allocation-pass { + background-color: rgb(32, 58, 24); +} +.part-allocation-underallocated { + background-color: rgb(58, 24, 24); +} +.part-allocation-overallocated { + background-color: rgb(0, 66, 82); +} +.treeview .node-disabled { + color: rgb(192, 187, 179); +} +.node-part-tree:not(.node-disabled):hover { + background-color: rgb(30, 32, 33); +} diff --git a/InvenTree/InvenTree/static/css/color-themes/darker.css b/InvenTree/InvenTree/static/css/color-themes/darker.css new file mode 100644 index 0000000000..94584912a4 --- /dev/null +++ b/InvenTree/InvenTree/static/css/color-themes/darker.css @@ -0,0 +1,42 @@ +/* Color Theme: "Darker" by Radek Hladik */ + +.navbar-nav > li { + border-color: rgb(179, 179, 179); +} + +.navbar-nav > li > a { + color:#0b2a62 !important; +} + +.navbar-nav > li > a:hover { + color:#202020 !important; +} + +.navbar-nav > .open > a { + color:#202020 !important; +} + +.navbar { + background-color: rgb(189, 189, 189); +} + +.table-condensed > tbody > tr > td { + border-top: 1px solid #062152 !important ; +} + +.table-striped > tbody > tr > td { + border-top: 1px solid #92b3f1 ; +} + +.table-bordered, .table-bordered > tbody > tr > td { + border: 1px solid rgb(182,182,182); +} + +.table-bordered > thead > tr > th { + border: 1px solid rgb(182, 182, 182); + background-color: rgb(235, 235, 235); +} + +h3 { + color:#06255d; +} diff --git a/InvenTree/InvenTree/static/css/color-themes/default.css b/InvenTree/InvenTree/static/css/color-themes/default.css new file mode 100644 index 0000000000..99e1632194 --- /dev/null +++ b/InvenTree/InvenTree/static/css/color-themes/default.css @@ -0,0 +1 @@ +/* Color Theme: "Default" */ \ No newline at end of file diff --git a/InvenTree/InvenTree/static/css/inventree-darker.css b/InvenTree/InvenTree/static/css/inventree-darker.css deleted file mode 100644 index 2df593b2fa..0000000000 --- a/InvenTree/InvenTree/static/css/inventree-darker.css +++ /dev/null @@ -1,785 +0,0 @@ -:root { - --primary-color: #335d88; - --secondary-color: #b69c80; - --highlight-color: #f5efe8; - --basic-color: #333; - - --label-red: #e35a57; - --label-blue: #4194bd; - --label-green: #50aa51; - --label-grey: #aaa; - --label-yellow: #fdc82a; -} - -.markdownx .row { - margin: 5px; - padding: 5px; - border: 1px solid #cce; - border-radius: 4px; -} - -.markdownx-editor { - width: 100%; - border: 1px solid #cce; - border-radius: 3px; - padding: 10px; -} - -.panel-content { - padding: 10px; -} - -.markdownx-preview { - border: 1px solid #cce; - border-radius: 3px; - padding: 10px; -} - -/* Progress bars */ - -.progress { - position: relative; - width: 100%; - margin-bottom: 0px; - background: #eeeef5; -} - -.progress-bar { - opacity: 60%; - background: #2aa02a; -} - -.progress-bar-under { - background: #eeaa33; -} - -.progress-bar-over { - background: #337ab7; -} - -.progress-value { - width: 100%; - color: #333; - position: absolute; - text-align: center; - top: 0px; - left: 0px; - font-size: 110%; -} - -.qr-code { - max-width: 400px; - max-height: 400px; - align-content: center; -} - -.qr-container { - width: 100%; - align-content: center; -} - -.navbar-brand { - float: left; -} - -.navbar-barcode-li { - border-left: none; - border-right: none; -} - -.navbar-nav > li { - border-left: 1px solid; - border-right: 1px solid; - border-color: rgb(179, 179, 179); - -} - -.navbar-nav > li > a { - color:#0b2a62 !important; -} - -.navbar-nav > li > a:hover { - color:#202020 !important; -} - -.navbar-nav > .open > a { - color:#202020 !important; -} - - - - -.navbar-form { - padding-right: 3px; -} - -.navbar { - background-color: rgb(189, 189, 189); -} - -.table-condensed > tbody > tr > td { - border-top: 1px solid #062152 !important ; -} - -.table-striped > tbody > tr > td { - border-top: 1px solid #92b3f1 ; -} - -.table-bordered, .table-bordered > tbody > tr > td { - border: 1px solid rgb(182,182,182); -} - -.table-bordered > thead > tr > th { - border: 1px solid rgb(182, 182, 182); - background-color: rgb(235, 235, 235); -} - -h3 { - color:#06255d; -} - -#barcode-scan { - margin-top: 8px; -} - -.icon-header { - margin-right: 10px; -} - -.glyphicon { - font-size: 18px; -} - - -.glyphicon-small { - font-size: 12px; -} - -.glyphicon-right { - float: right; -} - -.starred-part { - color: #ffbb00; -} - -.red-cell { - background-color: #ec7f7f; -} - -.part-price { - color: rgb(13, 245, 25); -} - -.icon-red { - color: #c55; -} - -.icon-green { - color: #43bb43; -} - -.icon-blue { - color: #55c; -} - -.icon-yellow { - color: #CC2; -} - -/* CSS overrides for treeview */ -.expand-icon { - font-size: 11px; -} - -.treeview .badge { - font-size: 10px; -} - -.treeview .list-group-item { - padding: 6px 12px; -} - -.list-group-item-condensed { - padding: 5px 10px; -} - -/* Extra label styles */ - -.label-large { - margin: 3px; - font-size: 100%; - border: 3px solid; - border-radius: 15px; - background: none; - padding-right: 10px; - padding-left: 10px; - padding-top: 5px; - padding-bottom: 5px; -} - -.label-large-red { - color: var(--label-red); - border-color: var(--label-red); -} - -.label-red { - background: var(--label-red); -} - -.label-large-blue { - color: var(--label-blue); - border-color: var(--label-blue); -} - -.label-blue { - background: var(--label-blue); -} - -.label-large-green { - color: var(--label-green); - border-color: var(--label-green); -} - -.label-green { - background: var(--label-green); -} - -.label-large-grey { - color: var(--label-grey); - border-color: var(--label-grey); -} - -.label-grey { - background: var(--label-grey); -} - -.label-large-yellow { - color: var(--label-yellow); - border-color: var(--label-yellow); -} - -.label-yellow { - background: var(--label-yellow); -} - -.label-right { - float: right; - margin-left: 3px; - margin-right: 3px; -} - -/* Bootstrap table overrides */ - -.stock-sub-group td { - background-color: #ebf4f4; -} - -.sub-table { - margin-left: 45px; - margin-right: 45px; -} - -.detail-icon .glyphicon { - color: #98d296; -} - -/* Force select2 elements in modal forms to be full width */ -.select-full-width { - width: 100%; -} - -.basecurrency { - color: #050; - font-style: italic; - font-weight: bold; -} - -.bomselect { - max-width: 250px; -} - -.rowvalid { - color: #050; -} - -.rowinvalid { - color: #A00; - font-style: italic; -} - -.dropdown { - padding-left: 1px; - margin-left: 1px; -} - -.dropdown-buttons { - display: inline-block -} - -.dropdown-menu .open{ - z-index: 1000; - position: relative; - overflow: visible; -} - -/* Styles for table buttons and filtering */ -.button-toolbar .btn { - margin-left: 1px; - margin-right: 1px; -} - -.filter-list { - display: inline-block; - *display: inline; - margin-bottom: 1px; - margin-top: 1px; - vertical-align: middle; - margin: 1px; - padding: 2px; - background: #eee; - border: 1px solid #eee; - border-radius: 3px; -} - -.filter-list .close { - cursor: pointer; - right: 0%; - padding-right: 2px; - padding-left: 2px; - transform: translate(0%, -25%); -} - -.filter-list .close:hover {background: #bbb;} - -.filter-tag { - display: inline-block; - *display: inline; - zoom: 1; - padding-left: 3px; - padding-right: 3px; - padding-top: 2px; - padding-bottom: 2px; - border: 1px solid #aaa; - border-radius: 3px; - background: #eee; - margin: 1px; - margin-left: 5px; - margin-right: 5px; -} - -.filter-input { - display: inline-block; - *display: inline; - zoom: 1; -} - -.filter-tag:hover { - background: #ddd; -} - -/* Part image icons with full-display on mouse hover */ - -.hover-img-thumb { - background: #eee; - width: 28px; - height: 28px; - object-fit: contain; - border: 1px solid #cce; -} - -.hover-img-large { - background: #eee; - display: none; - position: absolute; - z-index: 400; - border: 1px solid #555; - max-width: 250px; -} - -.hover-icon { - margin-right: 10px; -} - -.hover-icon:hover > .hover-img-large { - display: block; -} - -/* dropzone class - for Drag-n-Drop file uploads */ -.dropzone { - z-index: 2; -} - -/* -.dropzone * { - pointer-events: none; -} -*/ - -.dragover { - background-color: #55A; - border: 1px dashed #111; - opacity: 0.1; - -moz-opacity: 10%; - -webkit-opacity: 10%; -} - -/* grid display for part images */ - -.table-img-grid tr { - display: inline; -} - -.table-img-grid td { - padding: 10px; - margin: 10px; -} - -.table-img-grid .grid-image { - - height: 128px; - width: 128px; - object-fit: contain; - background: #eee; -} - -.btn-glyph { - padding-left: 6px; - padding-right: 6px; - padding-top: 3px; - padding-bottom: 2px; -} - -.action-button { - font-size: 125%; -} - -.action-buttons .btn { - font-size: 175%; - align-content: center; - vertical-align: middle; - padding-left: 6px; - padding-right: 6px; - padding-top: 3px; - padding-bottom: 2px; -}; - -.panel-heading .badge { - float: right; -} - -.badge { - float: right; - background-color: #777; - color: #fff; - border-radius: 5px; - margin-left: 10px; -} - -.badge-alert { - background-color: #f33; -} - -.part-thumb { - width: 200px; - height: 200px; - margin: 2px; - padding: 3px; - object-fit: contain; - border: 1px solid #aaa; - border-radius: 3px; -} - -.part-thumb-container:hover .part-thumb-overlay { - opacity: 1; -} - -.part-thumb-overlay { - position: absolute; - top: 0; - left: 0; - opacity: 0; - transition: .25s ease; - padding: 15px; - margin: 5px; -} - -.checkbox { - margin-left: 20px; -} - -.checkboxinput { - padding-left: 5px; - padding-right: 5px; -} - -.media { - padding-top: 15px; -} - -.media-body { - padding-top: 10px; - overflow: visible; -} - -.navigation { -} - -.nav-tabs { - margin-bottom: 20px; -} - -.settings-container { - width: 90%; - padding: 15px; -} - -.settings-nav { - height: 100%; - width: 160px; - position: fixed; - z-index: 1; - //top: 0; - //left: 0; - overflow-x: hidden; - padding-top: 20px; - padding-right: 25px; -} - -.settings-content { - margin-left: 175px; - padding: 0px 10px; -} - -.breadcrump { - margin-bottom: 5px; -} - -.inventree-body { - width: 100%; - padding: 5px; - margin: 10px; -} - -.inventree-pre-content { - width: 100%; - clear: both; -} - -.inventree-content { - padding-left: 5px; - padding-right: 5px; - padding-top: 5px; - width: auto; - transition: 0.1s; -} - -.body { - padding-top: 70px; -} - -.modal { - overflow: hidden; - z-index: 9999; -} - -.modal-primary { - z-index: 10000; -} - -.modal-secondary { - z-index: 11000; -} - -.js-modal-form .checkbox { - margin-left: 0px; -} - -.modal-dialog { - width: 60%; -} - -.modal-secondary .modal-dialog { - width: 40%; - padding-top: 15px; -} - -.modal-content h3 { - margin-top: 3px; - margin-bottom: 3px; -} - -.modal-form-content { - border-radius: 0; - position:relative; - height: auto !important; - max-height: calc(100vh - 200px) !important; - overflow-y: scroll; - padding: 10px; -} - -.modal input { - width: 100%; -} - -input[type="submit"] { - color: #333; - background-color: #e6e6e6; - border-color: #adadad; -} - -.modal textarea { - width: 100%; -} - -/* Force a control-label div to be 100% width */ -.modal .control-label { - width: 100%; - margin-top: 5px; -} - -.modal .control-label .btn { - padding-top: 3px; - padding-bottom: 3px; -} - -.modal .btn-secondary { - background-color: #5e7d87; -} - -/* The side navigation menu */ -.sidenav { - height: 100%; /* 100% Full-height */ - width: 0px; /* 0 width - change this with JavaScript */ - position: fixed; /* Stay in place */ - background-color: #fff; /* Black*/ - overflow-x: hidden; /* Disable horizontal scroll */ - transition: 0.1s; /* 0.5 second transition effect to slide in the sidenav */ -} - -.wrapper { - align-items: stretch; - display: flex; -} - -.help-inline { - color: #A11; -} - -.notification-area { - position: fixed; - top: 0px; - margin-top: 20px; - width: 100%; - padding: 20px; - z-index: 5000; - pointer-events: none; // Prevent this div from blocking links underneath -} - -.alert { - display: none; - border-radius: 5px; - opacity: 0.9; - pointer-events: all; -} - -.alert-block { - display: block; -} - -.btn { - margin-left: 2px; - margin-right: 2px; -} - -.btn-remove { - padding: 3px; - padding-left: 5px; - padding-right: 5px; - color: #A11; -} - -.btn-create { - padding: 3px; - padding-left: 5px; - padding-right: 5px; - color: #1A1; -} - -.btn-edit { - padding: 3px; - padding: 3px; - padding-left: 5px; - padding-right: 5px; - color: #55E; -} - -.button-toolbar { - padding-left: 0px; -} - -.panel-group { - margin-bottom: 5px; -} - -.panel-body { - padding: 10px; -} - -.panel-group .panel { - border-radius: 2px; -} - -.panel-heading { - padding: 5px 10px; - background-color: #fafafa; -} - -.float-right { - float: right; -} - -.warning-msg { - color: #e00; -} - -.login { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - -.part-allocation { - padding: 3px 10px; - border: 1px solid #ccc; - border-radius: 2px; -} - -.part-allocation-pass { - background-color: #dbf0db; -} - -.part-allocation-underallocated { - background-color: #f0dbdb; -} - -.part-allocation-overallocated { - background-color: #ccf5ff; -} - -.glyphicon-refresh-animate { - -animation: spin .7s infinite linear; - -webkit-animation: spin2 .7s infinite linear; -} - -@-webkit-keyframes spin2 { - from { -webkit-transform: rotate(0deg);} - to { -webkit-transform: rotate(360deg);} -} - -@keyframes spin { - from { transform: scale(1) rotate(0deg);} - to { transform: scale(1) rotate(360deg);} -} - diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 2b7eeb497c..4de5a037e9 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -157,11 +157,12 @@ class Currency(models.Model): class ColorTheme(models.Model): - """ Color Theme setting """ + """ Color Theme Setting """ class ColorThemeChoices(models.TextChoices): DEFAULT = '', _('Default') - DARKER = '-darker', _('Darker') + DARKER = 'darker', _('Darker') + DARK_READER = 'dark-reader', _('Dark Reader') name = models.CharField(max_length=20, choices=ColorThemeChoices.choices, diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 0026c5e7f8..55e6ae4eb8 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -1,6 +1,7 @@ """ This module provides template tags for extra functionality over and above the built-in Django tags. """ +import os from django import template from InvenTree import version, settings @@ -91,9 +92,18 @@ def inventree_setting(key, *args, **kwargs): @register.simple_tag() -def get_theme_css(username): +def get_color_theme_css(username): try: user_theme = ColorTheme.objects.filter(user=username).get().name + if not user_theme: + user_theme = 'default' except ColorTheme.DoesNotExist: - user_theme = '' - return f'{settings.STATIC_URL}css/inventree' + user_theme + '.css' + user_theme = 'default' + + # Build path to CSS sheet + inventree_css_sheet = os.path.join('css', 'color-themes', user_theme + '.css') + + # Build static URL + inventree_css_static_url = os.path.join(settings.STATIC_URL, inventree_css_sheet) + + return inventree_css_static_url diff --git a/InvenTree/templates/InvenTree/settings/theme.html b/InvenTree/templates/InvenTree/settings/theme.html index 55d6745281..dcccb7d4c9 100644 --- a/InvenTree/templates/InvenTree/settings/theme.html +++ b/InvenTree/templates/InvenTree/settings/theme.html @@ -14,16 +14,10 @@ -
-
-
-
- {% csrf_token %} - {% load crispy_forms_tags %} - {% crispy form %} -
-
-
-
+
+ {% csrf_token %} + {% load crispy_forms_tags %} + {% crispy form %} +
{% endblock %} diff --git a/InvenTree/templates/base.html b/InvenTree/templates/base.html index b622fbed26..db98617614 100644 --- a/InvenTree/templates/base.html +++ b/InvenTree/templates/base.html @@ -39,7 +39,8 @@ - + + {% block css %} {% endblock %} From 8198fad6d52f0bed8605a828d9ee60cb58eca88f Mon Sep 17 00:00:00 2001 From: eeintech Date: Tue, 8 Sep 2020 16:36:58 -0500 Subject: [PATCH 6/7] Updated common.colortheme migration --- InvenTree/common/migrations/0007_colortheme.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/InvenTree/common/migrations/0007_colortheme.py b/InvenTree/common/migrations/0007_colortheme.py index b0455073a0..c56e1c58fd 100644 --- a/InvenTree/common/migrations/0007_colortheme.py +++ b/InvenTree/common/migrations/0007_colortheme.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.7 on 2020-09-07 21:13 +# Generated by Django 3.0.7 on 2020-09-08 21:35 from django.db import migrations, models @@ -14,7 +14,7 @@ class Migration(migrations.Migration): name='ColorTheme', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(blank=True, choices=[('', 'Default'), ('-darker', 'Darker')], default='', max_length=20)), + ('name', models.CharField(blank=True, choices=[('', 'Default'), ('darker', 'Darker'), ('dark-reader', 'Dark Reader')], default='', max_length=20)), ('user', models.CharField(max_length=150)), ], ), From 28585644eadb5af6b2ab69438470c27d9b772e1c Mon Sep 17 00:00:00 2001 From: eeintech Date: Wed, 9 Sep 2020 14:55:32 -0500 Subject: [PATCH 7/7] Added automatic listing of custom CSS sheets (no more hardcoded), added error message when current selection is not valid and select default theme --- InvenTree/InvenTree/forms.py | 6 ++ InvenTree/InvenTree/settings.py | 3 + InvenTree/InvenTree/views.py | 59 ++++++++++++++----- .../common/migrations/0007_colortheme.py | 6 +- InvenTree/common/models.py | 47 ++++++++++++--- .../part/templatetags/inventree_extras.py | 11 ++-- .../templates/InvenTree/settings/theme.html | 11 +++- 7 files changed, 112 insertions(+), 31 deletions(-) diff --git a/InvenTree/InvenTree/forms.py b/InvenTree/InvenTree/forms.py index 87381b775a..80df8914d3 100644 --- a/InvenTree/InvenTree/forms.py +++ b/InvenTree/InvenTree/forms.py @@ -167,6 +167,8 @@ class SetPasswordForm(HelperForm): class ColorThemeSelectForm(forms.ModelForm): """ Form for setting color theme """ + name = forms.ChoiceField(choices=(), required=False) + class Meta: model = ColorTheme fields = [ @@ -175,6 +177,10 @@ class ColorThemeSelectForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(ColorThemeSelectForm, self).__init__(*args, **kwargs) + + # Populate color themes choices + self.fields['name'].choices = ColorTheme.get_color_themes_choices() + self.helper = FormHelper() # Form rendering self.helper.form_show_labels = False diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 24ba9278c8..7e398a9c34 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -82,6 +82,9 @@ STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'InvenTree', 'static'), ] +# Color Themes Directory +STATIC_COLOR_THEMES_DIR = os.path.join(STATIC_ROOT, 'css', 'color-themes') + # Web URL endpoint for served media files MEDIA_URL = '/media/' diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 69649edad9..3f9bc5b0a9 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -565,7 +565,7 @@ class ColorThemeSelectView(FormView): template_name = "InvenTree/settings/theme.html" def get_user_theme(self): - """ Get user color theme """ + """ Get current user color theme """ try: user_theme = ColorTheme.objects.filter(user=self.request.user).get() except ColorTheme.DoesNotExist: @@ -574,32 +574,61 @@ class ColorThemeSelectView(FormView): return user_theme def get_initial(self): - """ Select user theme """ + """ Select current user color theme as initial choice """ + initial = super(ColorThemeSelectView, self).get_initial() + user_theme = self.get_user_theme() if user_theme: initial['name'] = user_theme.name return initial - def post(self, request, *args, **kwargs): - """ Save user color theme """ - form = self.get_form() - if form.is_valid(): - theme_select = form.cleaned_data['name'] - # Get current user theme - user_theme = self.get_user_theme() - - # Create theme entry if user did not select one yet - if not user_theme: - user_theme = ColorTheme() + def get(self, request, *args, **kwargs): + """ Check if current color theme exists, else display alert box """ + context = {} + + form = self.get_form() + context['form'] = form + + user_theme = self.get_user_theme() + if user_theme: + # Check color theme is a valid choice + if not ColorTheme.is_valid_choice(user_theme): + user_color_theme_name = user_theme.name + if not user_color_theme_name: + user_color_theme_name = 'default' + + context['invalid_color_theme'] = user_color_theme_name + + return self.render_to_response(context) + + def post(self, request, *args, **kwargs): + """ Save user color theme selection """ + + form = self.get_form() + + # Get current user theme + user_theme = self.get_user_theme() + + # Create theme entry if user did not select one yet + if not user_theme: + user_theme = ColorTheme() + user_theme.user = request.user + + if form.is_valid(): + theme_selected = form.cleaned_data['name'] + # Set color theme to form selection - user_theme.user = str(request.user) - user_theme.name = theme_select + user_theme.name = theme_selected user_theme.save() return self.form_valid(form) else: + # Set color theme to default + user_theme.name = ColorTheme.default_color_theme[0] + user_theme.save() + return self.form_invalid(form) diff --git a/InvenTree/common/migrations/0007_colortheme.py b/InvenTree/common/migrations/0007_colortheme.py index c56e1c58fd..467e3e835f 100644 --- a/InvenTree/common/migrations/0007_colortheme.py +++ b/InvenTree/common/migrations/0007_colortheme.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.7 on 2020-09-08 21:35 +# Generated by Django 3.0.7 on 2020-09-09 19:50 from django.db import migrations, models @@ -14,8 +14,8 @@ class Migration(migrations.Migration): name='ColorTheme', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(blank=True, choices=[('', 'Default'), ('darker', 'Darker'), ('dark-reader', 'Dark Reader')], default='', max_length=20)), - ('user', models.CharField(max_length=150)), + ('name', models.CharField(blank=True, default='', max_length=20)), + ('user', models.CharField(max_length=150, unique=True)), ], ), ] diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 4de5a037e9..b8e9959f01 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -6,7 +6,10 @@ These models are 'generic' and do not fit a particular business logic object. # -*- coding: utf-8 -*- from __future__ import unicode_literals +import os + from django.db import models +from django.conf import settings from django.utils.translation import ugettext as _ from django.core.validators import MinValueValidator, MaxValueValidator from django.core.exceptions import ValidationError @@ -159,14 +162,44 @@ class Currency(models.Model): class ColorTheme(models.Model): """ Color Theme Setting """ - class ColorThemeChoices(models.TextChoices): - DEFAULT = '', _('Default') - DARKER = 'darker', _('Darker') - DARK_READER = 'dark-reader', _('Dark Reader') + default_color_theme = ('', _('Default')) name = models.CharField(max_length=20, - choices=ColorThemeChoices.choices, - default=ColorThemeChoices.DEFAULT, + default='', blank=True) - user = models.CharField(max_length=150) + user = models.CharField(max_length=150, + unique=True) + + @classmethod + def get_color_themes_choices(cls): + """ Get all color themes from static folder """ + + # Get files list from css/color-themes/ folder + files_list = [] + for file in os.listdir(settings.STATIC_COLOR_THEMES_DIR): + files_list.append(os.path.splitext(file)) + + # Get color themes choices (CSS sheets) + choices = [(file_name.lower(), _(file_name.replace('-', ' ').title())) + for file_name, file_ext in files_list + if file_ext == '.css' and file_name.lower() != 'default'] + + # Add default option as empty option + choices.insert(0, cls.default_color_theme) + + return choices + + @classmethod + def is_valid_choice(cls, user_color_theme): + """ Check if color theme is valid choice """ + try: + user_color_theme_name = user_color_theme.name + except AttributeError: + return False + + for color_theme in cls.get_color_themes_choices(): + if user_color_theme_name == color_theme[0]: + return True + + return False diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 55e6ae4eb8..f7bf65abc0 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -94,14 +94,15 @@ def inventree_setting(key, *args, **kwargs): @register.simple_tag() def get_color_theme_css(username): try: - user_theme = ColorTheme.objects.filter(user=username).get().name - if not user_theme: - user_theme = 'default' + user_theme = ColorTheme.objects.filter(user=username).get() + user_theme_name = user_theme.name + if not user_theme_name or not ColorTheme.is_valid_choice(user_theme): + user_theme_name = 'default' except ColorTheme.DoesNotExist: - user_theme = 'default' + user_theme_name = 'default' # Build path to CSS sheet - inventree_css_sheet = os.path.join('css', 'color-themes', user_theme + '.css') + inventree_css_sheet = os.path.join('css', 'color-themes', user_theme_name + '.css') # Build static URL inventree_css_static_url = os.path.join(settings.STATIC_URL, inventree_css_sheet) diff --git a/InvenTree/templates/InvenTree/settings/theme.html b/InvenTree/templates/InvenTree/settings/theme.html index dcccb7d4c9..90f148b468 100644 --- a/InvenTree/templates/InvenTree/settings/theme.html +++ b/InvenTree/templates/InvenTree/settings/theme.html @@ -18,6 +18,15 @@ {% csrf_token %} {% load crispy_forms_tags %} {% crispy form %} - + + +{% if invalid_color_theme %} + +{% endif %} {% endblock %}