Merge pull request #2861 from matmair/matmair/issue2301

[FR] White labeling
This commit is contained in:
Oliver 2022-04-27 21:49:15 +10:00 committed by GitHub
commit bb5734d1ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 108 additions and 46 deletions

View File

@ -25,6 +25,7 @@ import moneyed
import yaml
from django.utils.translation import gettext_lazy as _
from django.contrib.messages import constants as messages
from django.core.files.storage import default_storage
import django.conf.locale
from .config import get_base_dir, get_config_file, get_plugin_file, get_setting
@ -913,3 +914,20 @@ PLUGIN_TESTING = get_setting('PLUGIN_TESTING', TESTING) # are plugins beeing te
PLUGIN_TESTING_SETUP = get_setting('PLUGIN_TESTING_SETUP', False) # load plugins from setup hooks in testing?
PLUGIN_RETRY = get_setting('PLUGIN_RETRY', 5) # how often should plugin loading be tried?
PLUGIN_FILE_CHECKED = False # Was the plugin file checked?
# user interface customization values
CUSTOMIZE = get_setting(
'INVENTREE_CUSTOMIZE',
CONFIG.get('customize', {}),
{}
)
CUSTOM_LOGO = get_setting(
'INVENTREE_CUSTOM_LOGO',
CUSTOMIZE.get('logo', False)
)
# check that the logo-file exsists in media
if CUSTOM_LOGO and not default_storage.exists(CUSTOM_LOGO):
CUSTOM_LOGO = False
logger.warning("The custom logo file could not be found in the default media storage")

View File

@ -684,7 +684,7 @@ class InvenTreeSetting(BaseInvenTreeSetting):
},
'INVENTREE_INSTANCE': {
'name': _('InvenTree Instance Name'),
'name': _('Server Instance Name'),
'default': 'InvenTree server',
'description': _('String descriptor for the server instance'),
},
@ -696,6 +696,13 @@ class InvenTreeSetting(BaseInvenTreeSetting):
'default': False,
},
'INVENTREE_RESTRICT_ABOUT': {
'name': _('Restrict showing `about`'),
'description': _('Show the `about` modal only to superusers'),
'validator': bool,
'default': False,
},
'INVENTREE_COMPANY_NAME': {
'name': _('Company name'),
'description': _('Internal company name'),
@ -1353,7 +1360,7 @@ class InvenTreeUserSetting(BaseInvenTreeSetting):
'STICKY_HEADER': {
'name': _('Fixed Navbar'),
'description': _('InvenTree navbar position is fixed to the top of the screen'),
'description': _('The navbar position is fixed to the top of the screen'),
'default': False,
'validator': bool,
},

View File

@ -63,8 +63,8 @@ class SettingsTest(TestCase):
report_test_obj = InvenTreeSetting.get_setting_object('REPORT_ENABLE_TEST_REPORT')
# check settings base fields
self.assertEqual(instance_obj.name, 'InvenTree Instance Name')
self.assertEqual(instance_obj.get_setting_name(instance_ref), 'InvenTree Instance Name')
self.assertEqual(instance_obj.name, 'Server Instance Name')
self.assertEqual(instance_obj.get_setting_name(instance_ref), 'Server Instance Name')
self.assertEqual(instance_obj.description, 'String descriptor for the server instance')
self.assertEqual(instance_obj.get_setting_description(instance_ref), 'String descriptor for the server instance')

View File

@ -1,9 +1,10 @@
{% extends "page_base.html" %}
{% load static %}
{% load i18n %}
{% load inventree_extras %}
{% block page_title %}
InvenTree | {% trans "Manufacturer Part" %}
{% inventree_title %} | {% trans "Manufacturer Part" %}
{% endblock %}
{% block sidebar %}

View File

@ -186,3 +186,10 @@ static_root: '/home/inventree/data/static'
# KEYCLOAK_URL: 'https://keycloak.custom/auth'
# KEYCLOAK_REALM: 'master'
# Customization options
# Add custom messages to the login page or main interface navbar or exchange the logo
# Use environment variable INVENTREE_CUSTOMIZE or INVENTREE_CUSTOM_LOGO
# customize:
# login_message: InvenTree demo instance - <a href='https://inventree.readthedocs.io/en/latest/demo/'> Click here for login details</a>
# navbar_message: <h6>InvenTree demo mode <a href='https://inventree.readthedocs.io/en/latest/demo/'><span class='fas fa-info-circle'></span></a></h6>
# logo: logo.png

View File

@ -18,7 +18,8 @@ from django.conf import settings as djangosettings
from django import template
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.templatetags.static import StaticNode
from django.templatetags.static import StaticNode, static
from django.core.files.storage import default_storage
from InvenTree import version, settings
@ -166,6 +167,14 @@ def inventree_demo_mode(*args, **kwargs):
return djangosettings.DEMO_MODE
@register.simple_tag()
def inventree_show_about(user, *args, **kwargs):
""" Return True if the about modal should be shown """
if InvenTreeSetting.get_setting('INVENTREE_RESTRICT_ABOUT') and not user.is_superuser:
return False
return True
@register.simple_tag()
def inventree_docker_mode(*args, **kwargs):
""" Return True if the server is running as a Docker image """
@ -220,8 +229,13 @@ def python_version(*args, **kwargs):
@register.simple_tag()
def inventree_version(*args, **kwargs):
def inventree_version(shortstring=False, *args, **kwargs):
""" Return InvenTree version string """
if shortstring:
return _("{title} v{version}".format(
title=version.inventreeInstanceTitle(),
version=version.inventreeVersion()
))
return version.inventreeVersion()
@ -512,6 +526,22 @@ def mail_configured():
return bool(settings.EMAIL_HOST)
@register.simple_tag()
def inventree_customize(reference, *args, **kwargs):
""" Return customization values for the user interface """
return djangosettings.CUSTOMIZE.get(reference, '')
@register.simple_tag()
def inventree_logo(*args, **kwargs):
""" Return the path to the logo-file """
if settings.CUSTOM_LOGO:
return default_storage.url(settings.CUSTOM_LOGO)
return static('img/inventree.png')
class I18nStaticNode(StaticNode):
"""
custom StaticNode

View File

@ -15,7 +15,7 @@ content: "v{{report_revision}} - {{ date.isoformat }}";
{% endblock %}
{% block bottom_center %}
content: "InvenTree v{% inventree_version %}";
content: "{% inventree_version shortstring=True %}";
{% endblock %}
{% block style %}

View File

@ -16,7 +16,7 @@ content: "v{{report_revision}} - {{ date.isoformat }}";
{% endblock %}
{% block bottom_center %}
content: "InvenTree v{% inventree_version %}";
content: "{% inventree_version shortstring=True %}";
{% endblock %}
{% block style %}

View File

@ -14,7 +14,7 @@ content: "{{ date.isoformat }}";
{% endblock %}
{% block bottom_center %}
content: "InvenTree v{% inventree_version %}";
content: "{% inventree_version shortstring=True %}";
{% endblock %}
{% block top_center %}

View File

@ -1,8 +1,9 @@
{% extends "base.html" %}
{% load i18n %}
{% load inventree_extras %}
{% block page_title %}
InvenTree | {% trans "Permission Denied" %}
{% inventree_title %} | {% trans "Permission Denied" %}
{% endblock %}
{% block content %}

View File

@ -1,8 +1,9 @@
{% extends "base.html" %}
{% load i18n %}
{% load inventree_extras %}
{% block page_title %}
InvenTree | {% trans "Page Not Found" %}
{% inventree_title %} | {% trans "Page Not Found" %}
{% endblock %}
{% block content %}

View File

@ -1,8 +1,9 @@
{% extends "base.html" %}
{% load i18n %}
{% load inventree_extras %}
{% block page_title %}
InvenTree | {% trans "Internal Server Error" %}
{% inventree_title %} | {% trans "Internal Server Error" %}
{% endblock %}
{% block content %}
@ -11,7 +12,7 @@ InvenTree | {% trans "Internal Server Error" %}
<h3>{% trans "Internal Server Error" %}</h3>
<div class='alert alert-danger alert-block'>
{% trans "The InvenTree server raised an internal error" %}<br>
{% blocktrans %}The {{ inventree_title }} server raised an internal error{% endblocktrans %}<br>
{% trans "Refer to the error log in the admin interface for further details" %}
</div>
</div>

View File

@ -30,7 +30,7 @@
<div class='container-fluid'>
<div class='clearfix content-heading login-header d-flex flex-wrap'>
<img class="pull-left" src="{% static 'img/inventree.png' %}" width="60" height="60"/>
<img class="pull-left" src="{% inventree_logo %}" width="60" height="60"/>
{% include "spacer.html" %}
<span class='float-right'><h3>{% block body_title %}{% trans 'Site is in Maintenance' %}{% endblock %}</h3></span>
</div>

View File

@ -15,6 +15,7 @@
<tbody>
{% include "InvenTree/settings/setting.html" with key="INVENTREE_INSTANCE" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_INSTANCE_TITLE" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_RESTRICT_ABOUT" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_BASE_URL" icon="fa-globe" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_COMPANY_NAME" icon="fa-building" %}
{% include "InvenTree/settings/setting.html" with key="INVENTREE_DOWNLOAD_FROM_URL" icon="fa-cloud-download-alt" %}

View File

@ -13,7 +13,7 @@
{% block content %}
<div class='alert alert-block alert-danger'>
{% trans "Changing the settings below require you to immediatly restart InvenTree. Do not change this while under active usage." %}
{% trans "Changing the settings below require you to immediatly restart the server. Do not change this while under active usage." %}
</div>
<div class='table-responsive'>

View File

@ -85,7 +85,7 @@
{% if plugin.is_package %}
{% trans "This plugin was installed as a package" %}
{% else %}
{% trans "This plugin was found in a local InvenTree path" %}
{% trans "This plugin was found in a local server path" %}
{% endif %}
</td>
</tr>

View File

@ -101,7 +101,7 @@
</div>
<div class="col-sm-6">
<h4>{% trans "Help the translation efforts!" %}</h4>
<p>{% blocktrans with link="https://crowdin.com/project/inventree" %}Native language translation of the InvenTree web application is <a href="{{link}}">community contributed via crowdin</a>. Contributions are welcomed and encouraged.{% endblocktrans %}</p>
<p>{% blocktrans with link="https://crowdin.com/project/inventree" %}Native language translation of the web application is <a href="{{link}}">community contributed via crowdin</a>. Contributions are welcomed and encouraged.{% endblocktrans %}</p>
</div>
</div>

View File

@ -67,7 +67,7 @@
<div class='container-fluid'>
<div class='clearfix content-heading login-header d-flex flex-wrap'>
<img class="pull-left" src="{% static 'img/inventree.png' %}" width="60" height="60"/>
<img class="pull-left" src="{% inventree_logo %}" width="60" height="60"/>
{% include "spacer.html" %}
<span class='float-right'><h3>{% inventree_title %}</h3></span>
</div>
@ -89,7 +89,7 @@
<script type='text/javascript' src="{% static 'script/jquery-ui/jquery-ui.min.js' %}"></script>
<script type="text/javascript" src="{% static 'bootstrap/js/bootstrap.bundle.min.js' %}"></script>
<!-- general InvenTree -->
<!-- general JS -->
<script type='text/javascript' src="{% static 'script/inventree/inventree.js' %}"></script>
<script type='text/javascript' src="{% i18n_static 'notification.js' %}"></script>

View File

@ -10,6 +10,7 @@
{% settings_value 'LOGIN_ENABLE_REG' as enable_reg %}
{% settings_value 'LOGIN_ENABLE_PWD_FORGOT' as enable_pwd_forgot %}
{% settings_value 'LOGIN_ENABLE_SSO' as enable_sso %}
{% inventree_customize 'login_message' as login_message %}
{% mail_configured as mail_conf %}
{% inventree_demo_mode as demo %}
@ -35,19 +36,15 @@ for a account and sign in below:{% endblocktrans %}</p>
{% endif %}
<hr>
{% if login_message %}
<div>{{ login_message }}<hr></div>
{% endif %}
<div class="btn-group float-right" role="group">
<button class="btn btn-success" type="submit">{% trans "Sign In" %}</button>
</div>
{% if mail_conf and enable_pwd_forgot and not demo %}
<a class="" href="{% url 'account_reset_password' %}"><small>{% trans "Forgot Password?" %}</small></a>
{% endif %}
{% if demo %}
<p>
<h6>
{% trans "InvenTree demo instance" %} - <a href='https://inventree.readthedocs.io/en/latest/demo/'>{% trans "Click here for login details" %}</a>
</h6>
</p>
{% endif %}
</form>
{% if enable_sso %}

View File

@ -7,6 +7,7 @@
{% settings_value "REPORT_ENABLE" as report_enabled %}
{% settings_value "SERVER_RESTART_REQUIRED" as server_restart_required %}
{% settings_value "LABEL_ENABLE" with user=user as labels_enabled %}
{% inventree_show_about user as show_about %}
{% inventree_demo_mode as demo_mode %}
<!DOCTYPE html>
@ -130,7 +131,7 @@
</div>
{% include 'modals.html' %}
{% include 'about.html' %}
{% if show_about %}{% include 'about.html' %}{% endif %}
{% include "notifications.html" %}
{% include "search.html" %}
</div>
@ -166,7 +167,7 @@
<script type='text/javascript' src="{% static 'script/clipboard.min.js' %}"></script>
<script type='text/javascript' src="{% static 'script/randomColor.min.js' %}"></script>
<!-- general InvenTree -->
<!-- general JS -->
<script type='text/javascript' src="{% static 'script/inventree/inventree.js' %}"></script>
<!-- dynamic javascript templates -->

View File

@ -32,7 +32,7 @@
{% block footer_prefix %}
<!-- Custom footer information goes here -->
{% endblock %}
<p><em><small>{% trans "InvenTree version" %}: {% inventree_version %} - <a href='https://inventree.readthedocs.io'>inventree.readthedocs.io</a></small></em></p>
<p><em><small>{% inventree_version shortstring=True %} - <a href='https://inventree.readthedocs.io'>readthedocs.io</a></small></em></p>
{% block footer_suffix %}
<!-- Custom footer information goes here -->
{% endblock %}

View File

@ -7,11 +7,13 @@
{% settings_value 'STICKY_HEADER' user=request.user as sticky %}
{% navigation_enabled as plugin_nav %}
{% inventree_demo_mode as demo %}
{% inventree_show_about user as show_about %}
{% inventree_customize 'navbar_message' as navbar_message %}
<nav class="navbar {% if sticky %}fixed-top{% endif %} navbar-expand-lg navbar-light">
<div class="container-fluid">
<div class="navbar-header clearfix content-heading">
<a class="navbar-brand" id='logo' href="{% url 'index' %}" style="padding-top: 7px; padding-bottom: 5px;"><img src="{% static 'img/inventree.png' %}" width="32" height="32" style="display:block; margin: auto;"/></a>
<a class="navbar-brand" id='logo' href="{% url 'index' %}" style="padding-top: 7px; padding-bottom: 5px;"><img src="{% inventree_logo %}" width="32" height="32" style="display:block; margin: auto;"/></a>
</div>
<div class="navbar-collapse collapse" id="navbar-objects">
<ul class="navbar-nav">
@ -84,8 +86,13 @@
</ul>
</div>
{% if demo %}
{% include "navbar_demo.html" %}
{% if navbar_message %}
{% include "spacer.html" %}
<div class='flex justify-content-center'>
{{ navbar_message }}
</div>
{% include "spacer.html" %}
{% include "spacer.html" %}
{% endif %}
<ul class='navbar-nav flex-row'>
@ -144,6 +151,7 @@
{% trans "System Information" %}
</a>
</li>
{% if show_about %}
<li id='launch-about'>
<a class='dropdown-item' href='#'>
{% if up_to_date %}
@ -154,6 +162,7 @@
{% trans "About InvenTree" %}
</a>
</li>
{% endif %}
</ul>
</li>
</ul>

View File

@ -1,12 +0,0 @@
{% load i18n %}
{% include "spacer.html" %}
<div class='flex'>
<h6>
{% trans "InvenTree demo mode" %}
<a href='https://inventree.readthedocs.io/en/latest/demo/'>
<span class='fas fa-info-circle'></span>
</a>
</h6>
</div>
{% include "spacer.html" %}
{% include "spacer.html" %}

View File

@ -75,7 +75,7 @@
<script type='text/javascript' src="{% static 'script/clipboard.min.js' %}"></script>
<script type='text/javascript' src="{% static 'script/randomColor.min.js' %}"></script>
<!-- general InvenTree -->
<!-- general JS -->
<script type='text/javascript' src="{% static 'script/inventree/inventree.js' %}"></script>
<script type='text/javascript' src="{% i18n_static 'notification.js' %}"></script>
{% block body_scripts_inventree %}