2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-18 13:05:42 +00:00

Merge branch 'master' of https://github.com/inventree/InvenTree into matmair/issue2279

This commit is contained in:
Matthias
2022-01-12 02:13:50 +01:00
96 changed files with 12549 additions and 10196 deletions

View File

@ -13,19 +13,19 @@
<table class='table table-striped table-condensed'>
<tbody>
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_SSO" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_PWD_FORGOT" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_MAIL_REQUIRED" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENFORCE_MFA" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_SSO" icon="fa-user-shield" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_PWD_FORGOT" icon="fa-user-lock" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_MAIL_REQUIRED" icon="fa-at" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENFORCE_MFA" icon='fa-key' %}
<tr>
<th><h5>{% trans 'Signup' %}</h5></th>
<td colspan='4'></td>
</tr>
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_REG" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_MAIL_TWICE" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_PWD_TWICE" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_SSO_AUTO" icon="fa-info-circle" %}
{% include "InvenTree/settings/setting.html" with key="SIGNUP_GROUP" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_ENABLE_REG" icon="fa-user-plus" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_MAIL_TWICE" icon="fa-at" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_PWD_TWICE" icon="fa-user-lock" %}
{% include "InvenTree/settings/setting.html" with key="LOGIN_SIGNUP_SSO_AUTO" icon="fa-key" %}
{% include "InvenTree/settings/setting.html" with key="SIGNUP_GROUP" icon="fa-users" %}
</tbody>
</table>

View File

@ -5,12 +5,12 @@
<h4>{% trans "Settings" %}</h4>
</div>
{% plugin_globalsettings plugin_key as plugin_settings %}
{% plugin_settings plugin_key as plugin_settings %}
<table class='table table-striped table-condensed'>
<tbody>
{% for setting in plugin_settings %}
{% include "InvenTree/settings/setting.html" with key=setting%}
{% include "InvenTree/settings/setting.html" with key=setting plugin=plugin %}
{% endfor %}
</tbody>
</table>

View File

@ -19,17 +19,18 @@
<div class='table-responsive'>
<table class='table table-striped table-condensed'>
<tbody>
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_URL" %}
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_NAVIGATION" %}
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_GLOBALSETTING"%}
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_APP"%}
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_SCHEDULE" icon="fa-calendar-alt" %}
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_EVENTS" icon="fa-reply-all" %}
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_URL" icon="fa-link" %}
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_NAVIGATION" icon="fa-sitemap" %}
{% include "InvenTree/settings/setting.html" with key="ENABLE_PLUGINS_APP" icon="fa-rocket" %}
</tbody>
</table>
</div>
<div class='panel-heading'>
<div class='d-flex flex-wrap'>
<h4>{% trans "Plugin list" %}</h4>
<h4>{% trans "Plugins" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% url 'admin:plugin_pluginconfig_changelist' as url %}
@ -70,7 +71,7 @@
{% if mixin_list %}
{% for mixin in mixin_list %}
<a class='sidebar-selector' id='select-plugin-{{plugin_key}}' data-bs-parent="#sidebar">
<span class='badge bg-dark badge-right'>{{ mixin.human_name }}</span>
<span class='badge bg-dark badge-right rounded-pill'>{{ mixin.human_name }}</span>
</a>
{% endfor %}
{% endif %}

View File

@ -90,7 +90,7 @@
</td>
</tr>
<tr>
<td></td>
<td><span class='fas fa-sitemap'></span></td>
<td>{% trans "Installation path" %}</td>
<td>{{ plugin.package_path }}</td>
</tr>

View File

@ -12,10 +12,10 @@
<table class='table table-striped table-condensed'>
<tbody>
{% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE" %}
{% include "InvenTree/settings/setting.html" with key="REPORT_DEFAULT_PAGE_SIZE" %}
{% include "InvenTree/settings/setting.html" with key="REPORT_DEBUG_MODE" %}
{% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE_TEST_REPORT" %}
{% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE" icon="fa-file-pdf" %}
{% include "InvenTree/settings/setting.html" with key="REPORT_DEFAULT_PAGE_SIZE" icon="fa-print" %}
{% include "InvenTree/settings/setting.html" with key="REPORT_DEBUG_MODE" icon="fa-laptop-code" %}
{% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE_TEST_REPORT" icon="fa-vial" %}
</tbody>
</table>

View File

@ -1,10 +1,12 @@
{% load inventree_extras %}
{% load i18n %}
{% if user_setting %}
{% setting_object key user=request.user as setting %}
{% if plugin %}
{% setting_object key plugin=plugin as setting %}
{% elif user_setting %}
{% setting_object key user=request.user as setting %}
{% else %}
{% setting_object key as setting %}
{% setting_object key as setting %}
{% endif %}
<tr>
@ -13,7 +15,7 @@
<span class='fas {{ icon }}'></span>
{% endif %}
</td>
<td><strong>{% trans setting.name %}</strong></td>
<td><strong>{{ setting.name }}</strong></td>
<td>
{% if setting.is_bool %}
<div class='form-check form-switch'>
@ -32,11 +34,11 @@
</div>
{% endif %}
<td>
{% trans setting.description %}
{{ setting.description }}
</td>
<td>
<div class='btn-group float-right'>
<button class='btn btn-outline-secondary btn-small btn-edit-setting' pk='{{ setting.pk }}' setting='{{ setting.key.upper }}' title='{% trans "Edit setting" %}' {% if user_setting %}user='{{request.user.id}}'{% endif %}>
<button class='btn btn-outline-secondary btn-small btn-edit-setting' pk='{{ setting.pk }}' setting='{{ setting.key.upper }}' title='{% trans "Edit setting" %}' {% if plugin %}plugin='{{ plugin.pk }}'{% endif %}{% if user_setting %}user='{{request.user.id}}'{% endif %}>
<span class='fas fa-edit icon-green'></span>
</button>
</div>

View File

@ -39,14 +39,17 @@
{% include "InvenTree/settings/build.html" %}
{% include "InvenTree/settings/po.html" %}
{% include "InvenTree/settings/so.html" %}
{% include "InvenTree/settings/plugin.html" %}
{% plugins_enabled as plug %}
{% if plug %}
{% include "InvenTree/settings/plugin.html" %}
{% plugin_list as pl_list %}
{% for plugin_key, plugin in pl_list.items %}
{% if plugin.registered_mixins %}
{% include "InvenTree/settings/plugin_settings.html" %}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
@ -62,16 +65,27 @@
$('table').find('.btn-edit-setting').click(function() {
var setting = $(this).attr('setting');
var pk = $(this).attr('pk');
var plugin = $(this).attr('plugin');
var is_global = true;
if ($(this).attr('user')){
is_global = false;
}
var title = '';
if (plugin != null) {
title = '{% trans "Edit Plugin Setting" %}';
} else if (is_global) {
title = '{% trans "Edit Global Setting" %}';
} else {
title = '{% trans "Edit User Setting" %}';
}
editSetting(pk, {
plugin: plugin,
global: is_global,
title: is_global ? '{% trans "Edit Global Setting" %}' : '{% trans "Edit User Setting" %}',
title: title,
});
});
@ -322,9 +336,12 @@ $("#import-part").click(function() {
launchModalForm("{% url 'api-part-import' %}?reset", {});
});
{% plugins_enabled as plug %}
{% if plug %}
$("#install-plugin").click(function() {
installPlugin();
});
{% endif %}
enableSidebar('settings');

View File

@ -47,15 +47,17 @@
{% trans "Sales Orders" as text %}
{% include "sidebar_item.html" with label='sales-order' text=text icon="fa-truck" %}
{% plugins_enabled as plug %}
{% if plug %}
{% include "sidebar_header.html" with text="Plugin Settings" %}
{% include "sidebar_item.html" with label='plugin' text="Plugin" icon="fa-plug" %}
{% include "sidebar_item.html" with label='plugin' text="Plugins" icon="fa-plug" %}
{% plugin_list as pl_list %}
{% for plugin_key, plugin in pl_list.items %}
{% if plugin.registered_mixins %}
{% include "sidebar_item.html" with label='plugin-'|add:plugin_key text=plugin.human_name %}
{% endif %}
{% if plugin.registered_mixins %}
{% include "sidebar_item.html" with label='plugin-'|add:plugin_key text=plugin.human_name %}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}

View File

@ -11,7 +11,6 @@
<table class='table table-striped table-condensed'>
<tbody>
{% include "InvenTree/settings/setting.html" with key="STOCK_GROUP_BY_PART" icon="fa-layer-group" %}
{% include "InvenTree/settings/setting.html" with key="STOCK_ENABLE_EXPIRY" icon="fa-stopwatch" %}
{% include "InvenTree/settings/setting.html" with key="STOCK_STALE_DAYS" icon="fa-calendar" %}
{% include "InvenTree/settings/setting.html" with key="STOCK_ALLOW_EXPIRED_SALE" icon="fa-truck" %}

View File

@ -214,88 +214,6 @@
</div>
</div>
<div class='row'>
<div class='panel-heading'>
<h4>{% trans "Theme Settings" %}</h4>
</div>
<div class='col-sm-6'>
<form action='{% url "settings-appearance" %}' method='post'>
{% csrf_token %}
<input name='next' type='hidden' value='{% url "settings" %}'>
<label for='theme' class=' requiredField'>
{% trans "Select theme" %}
</label>
<div class='form-group input-group mb-3'>
<select id='theme' name='theme' class='select form-control'>
{% get_available_themes as themes %}
{% for theme in themes %}
<option value='{{ theme.key }}'>{{ theme.name }}</option>
{% endfor %}
</select>
<div class='input-group-append'>
<input type="submit" value="{% trans 'Set Theme' %}" class="btn btn-primary">
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div class='panel-heading'>
<h4>{% trans "Language Settings" %}</h4>
</div>
<div class="col">
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{% url 'settings' %}">
<label for='language' class=' requiredField'>
{% trans "Select language" %}
</label>
<div class='form-group input-group mb-3'>
<select name="language" class="select form-control w-25">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% if 'alllang' in request.GET %}{% define True as ALL_LANG %}{% endif %}
{% for language in languages %}
{% define language.code as lang_code %}
{% define locale_stats|keyvalue:lang_code as lang_translated %}
{% if lang_translated > 10 or lang_code == 'en' or lang_code == LANGUAGE_CODE %}{% define True as use_lang %}{% else %}{% define False as use_lang %}{% endif %}
{% if ALL_LANG or use_lang %}
<option value="{{ lang_code }}"{% if lang_code == LANGUAGE_CODE %} selected{% endif %}>
{{ language.name_local }} ({{ lang_code }})
{% if lang_translated %}
{% blocktrans %}{{ lang_translated }}% translated{% endblocktrans %}
{% else %}
{% if lang_code == 'en' %}-{% else %}{% trans 'No translations available' %}{% endif %}
{% endif %}
</option>
{% endif %}
{% endfor %}
</select>
<div class='input-group-append'>
<input type="submit" value="{% trans 'Set Language' %}" class="btn btn btn-primary">
</div>
<p>{% trans "Some languages are not complete" %}
{% if ALL_LANG %}
. <a href="{% url 'settings' %}">{% trans "Show only sufficent" %}</a>
{% else %}
and hidden. <a href="?alllang">{% trans "Show them too" %}</a>
{% endif %}
</p>
</div>
</form>
</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>
</div>
</div>
<div class="row">
<div class='panel-heading'>
<div class='d-flex flex-wrap'>

View File

@ -6,6 +6,7 @@
{% settings_value 'REPORT_ENABLE_TEST_REPORT' as test_report_enabled %}
{% settings_value "REPORT_ENABLE" as report_enabled %}
{% settings_value "SERVER_RESTART_REQUIRED" as server_restart_required %}
{% inventree_demo_mode as demo_mode %}
<!DOCTYPE html>
<html lang="en">
@ -90,7 +91,7 @@
{% block alerts %}
<div class='notification-area' id='alerts'>
<!-- Div for displayed alerts -->
{% if server_restart_required %}
{% if server_restart_required and not demo_mode %}
<div id='alert-restart-server' class='alert alert-danger' role='alert'>
<span class='fas fa-server'></span>
<b>{% trans "Server Restart Required" %}</b>

View File

@ -28,9 +28,13 @@ function editSetting(pk, options={}) {
// Is this a global setting or a user setting?
var global = options.global || false;
var plugin = options.plugin;
var url = '';
if (global) {
if (plugin) {
url = `/api/plugin/settings/${pk}/`;
} else if (global) {
url = `/api/settings/global/${pk}/`;
} else {
url = `/api/settings/user/${pk}/`;

View File

@ -20,6 +20,7 @@
/* exported
allocateStockToBuild,
completeBuildOrder,
editBuildOrder,
loadAllocationTable,
loadBuildOrderAllocationTable,
@ -120,6 +121,60 @@ function newBuildOrder(options={}) {
}
/* Construct a form to "complete" (finish) a build order */
function completeBuildOrder(build_id, options={}) {
var url = `/api/build/${build_id}/finish/`;
var fields = {
accept_unallocated: {},
accept_incomplete: {},
};
var html = '';
if (options.allocated && options.completed) {
html += `
<div class='alert alert-block alert-success'>
{% trans "Build order is ready to be completed" %}
</div>`;
} else {
html += `
<div class='alert alert-block alert-danger'>
<strong>{% trans "Build Order is incomplete" %}</strong>
</div>
`;
if (!options.allocated) {
html += `<div class='alert alert-block alert-warning'>{% trans "Required stock has not been fully allocated" %}</div>`;
}
if (!options.completed) {
html += `<div class='alert alert-block alert-warning'>{% trans "Required build quantity has not been completed" %}</div>`;
}
}
// Hide particular fields if they are not required
if (options.allocated) {
delete fields.accept_unallocated;
}
if (options.completed) {
delete fields.accept_incomplete;
}
constructForm(url, {
fields: fields,
reload: true,
confirm: true,
method: 'POST',
title: '{% trans "Complete Build Order" %}',
preFormContent: html,
});
}
/*
* Construct a set of output buttons for a particular build output
*/

View File

@ -305,7 +305,16 @@ function setupFilterList(tableKey, table, target) {
var title = getFilterTitle(tableKey, key);
var description = getFilterDescription(tableKey, key);
element.append(`<div title='${description}' class='filter-tag'>${title} = ${value}<span ${tag}='${key}' class='close'>x</span></div>`);
var filter_tag = `
<div title='${description}' class='filter-tag'>
${title} = ${value}
<span ${tag}='${key}' class='close' style='color: #F55;'>
<span aria-hidden='true'><strong>&times;</strong></span>
</span>
</div>
`;
element.append(filter_tag);
}
// Callback for reloading the table

View File

@ -555,13 +555,18 @@ function renderErrorMessage(xhr) {
}
function showAlertDialog(title, content) {
function showAlertDialog(title, content, options={}) {
/* Display a modal dialog message box.
*
* title - Title text
* content - HTML content of the dialog window
*/
if (options.alert_style) {
// Wrap content in an alert block
content = `<div class='alert alert-block alert-${options.alert_style}'>${content}</div>`;
}
var modal = createNewModal({
title: title,

View File

@ -345,6 +345,12 @@ function editPart(pk) {
// Launch form to duplicate a part
function duplicatePart(pk, options={}) {
var title = '{% trans "Duplicate Part" %}';
if (options.variant) {
title = '{% trans "Create Part Variant" %}';
}
// First we need all the part information
inventreeGet(`/api/part/${pk}/`, {}, {
@ -372,7 +378,7 @@ function duplicatePart(pk, options={}) {
method: 'POST',
fields: fields,
groups: partGroups(),
title: '{% trans "Duplicate Part" %}',
title: title,
data: data,
onSuccess: function(data) {
// Follow the new part

View File

@ -111,12 +111,17 @@ function stockLocationFields(options={}) {
},
name: {},
description: {},
owner: {},
};
if (options.parent) {
fields.parent.value = options.parent;
}
if (!global_settings.STOCK_OWNERSHIP_CONTROL) {
delete fields['owner'];
}
return fields;
}
@ -130,6 +135,8 @@ function editStockLocation(pk, options={}) {
options.fields = stockLocationFields(options);
options.title = '{% trans "Edit Stock Location" %}';
constructForm(url, options);
}

View File

@ -371,7 +371,12 @@ function customGroupSorter(sortName, sortOrder, sortData) {
return `${pageNumber} {% trans "rows per page" %}`;
},
formatShowingRows: function(pageFrom, pageTo, totalRows) {
return `{% trans "Showing" %} ${pageFrom} {% trans "to" %} ${pageTo} {% trans "of" %} ${totalRows} {% trans "rows" %}`;
if (totalRows === undefined || totalRows === NaN) {
return '{% trans "Showing all rows" %}';
} else {
return `{% trans "Showing" %} ${pageFrom} {% trans "to" %} ${pageTo} {% trans "of" %} ${totalRows} {% trans "rows" %}`;
}
},
formatSearch: function() {
return '{% trans "Search" %}';

View File

@ -119,7 +119,7 @@
<ul class='dropdown-menu dropdown-menu-end inventree-navbar-menu'>
{% if user.is_authenticated %}
{% if user.is_staff and not demo %}
<li><a class='dropdown-item' href="/admin/"><span class="fas fa-user"></span> {% trans "Admin" %}</a></li>
<li><a class='dropdown-item' href="/admin/"><span class="fas fa-user-shield"></span> {% trans "Admin" %}</a></li>
{% endif %}
<li><a class='dropdown-item' href="{% url 'account_logout' %}"><span class="fas fa-sign-out-alt"></span> {% trans "Logout" %}</a></li>
{% else %}

View File

@ -34,6 +34,18 @@
<td>{% trans "Server is deployed using docker" %}</td>
</tr>
{% endif %}
<tr>
<td><span class='fas fa-plug'></span></td>
<td>{% trans "Plugin Support" %}</td>
<td>
{% plugins_enabled as p_en %}
{% if p_en %}
<span class='badge rounded-pill bg-success'>{% trans "Plugin support enabled" %}</span>
{% else %}
<span class='badge rounded-pill bg-warning'>{% trans "Plugin support disabled" %}</span>
{% endif %}
</td>
</tr>
{% if user.is_staff %}
<tr>
<td><span class='fas fa-server'></span></td>