Added automatic listing of custom CSS sheets (no more hardcoded), added error message when current selection is not valid and select default theme

This commit is contained in:
eeintech 2020-09-09 14:55:32 -05:00
parent 8198fad6d5
commit 28585644ea
7 changed files with 112 additions and 31 deletions

View File

@ -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

View File

@ -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/'

View File

@ -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)

View File

@ -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)),
],
),
]

View File

@ -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

View File

@ -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)

View File

@ -18,6 +18,15 @@
{% csrf_token %}
{% load crispy_forms_tags %}
{% crispy form %}
</form>
</form>
{% if invalid_color_theme %}
<div class="alert alert-danger alert-block" role="alert" style="display: inline-block;">
{% blocktrans %}
The CSS sheet "{{invalid_color_theme}}.css" for the currently selected color theme was not found.<br>
Please select another color theme :)
{% endblocktrans %}
</div>
{% endif %}
{% endblock %}