mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Feature/icons for PartCategory and StockLocation (#3542)
* Added icon to stock location - added `icon` field to `stock_stocklocation` model - added input field to stock location form - added icon to breadcrumb treeview in header - added icon to sub-locations table - added icon to location detail information - added `STOCK_LOCATION_DEFAULT_ICON` setting as default * Added icon to part category - added `icon` field to `part_partcategory` model - added input field to part category form - added icon to breadcrumb treeview in header - added icon to sub-categories table - added icon to category detail information - added `PART_CATEGORY_DEFAULT_ICON` setting as default * Added `blocktrans` to allowed tags in ci check * fix: style * Added `endblocktrans` to allowed tags in ci check * fix: missing `,` in ci check allowed tags script * Removed blocktrans from js and fixed style
This commit is contained in:
parent
1b76828305
commit
b9f83eefc8
@ -1028,3 +1028,8 @@ a {
|
|||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.treeview .node-icon {
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
margin-right: 0.25rem;
|
||||||
|
}
|
||||||
|
@ -1070,6 +1070,12 @@ class InvenTreeSetting(BaseInvenTreeSetting):
|
|||||||
'validator': InvenTree.validators.validate_part_name_format
|
'validator': InvenTree.validators.validate_part_name_format
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'PART_CATEGORY_DEFAULT_ICON': {
|
||||||
|
'name': _('Part Category Default Icon'),
|
||||||
|
'description': _('Part category default icon (empty means no icon)'),
|
||||||
|
'default': '',
|
||||||
|
},
|
||||||
|
|
||||||
'LABEL_ENABLE': {
|
'LABEL_ENABLE': {
|
||||||
'name': _('Enable label printing'),
|
'name': _('Enable label printing'),
|
||||||
'description': _('Enable label printing from the web interface'),
|
'description': _('Enable label printing from the web interface'),
|
||||||
@ -1168,6 +1174,12 @@ class InvenTreeSetting(BaseInvenTreeSetting):
|
|||||||
'validator': bool,
|
'validator': bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'STOCK_LOCATION_DEFAULT_ICON': {
|
||||||
|
'name': _('Stock Location Default Icon'),
|
||||||
|
'description': _('Stock location default icon (empty means no icon)'),
|
||||||
|
'default': '',
|
||||||
|
},
|
||||||
|
|
||||||
'BUILDORDER_REFERENCE_PATTERN': {
|
'BUILDORDER_REFERENCE_PATTERN': {
|
||||||
'name': _('Build Order Reference Pattern'),
|
'name': _('Build Order Reference Pattern'),
|
||||||
'description': _('Required pattern for generating Build Order reference field'),
|
'description': _('Required pattern for generating Build Order reference field'),
|
||||||
|
18
InvenTree/part/migrations/0084_partcategory_icon.py
Normal file
18
InvenTree/part/migrations/0084_partcategory_icon.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.15 on 2022-08-15 08:38
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('part', '0083_auto_20220731_2357'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='partcategory',
|
||||||
|
name='icon',
|
||||||
|
field=models.CharField(blank=True, help_text='Icon (optional)', max_length=100, verbose_name='Icon'),
|
||||||
|
),
|
||||||
|
]
|
@ -101,6 +101,13 @@ class PartCategory(MetadataMixin, InvenTreeTree):
|
|||||||
|
|
||||||
default_keywords = models.CharField(null=True, blank=True, max_length=250, verbose_name=_('Default keywords'), help_text=_('Default keywords for parts in this category'))
|
default_keywords = models.CharField(null=True, blank=True, max_length=250, verbose_name=_('Default keywords'), help_text=_('Default keywords for parts in this category'))
|
||||||
|
|
||||||
|
icon = models.CharField(
|
||||||
|
blank=True,
|
||||||
|
max_length=100,
|
||||||
|
verbose_name=_("Icon"),
|
||||||
|
help_text=_("Icon (optional)")
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_api_url():
|
def get_api_url():
|
||||||
"""Return the API url associated with the PartCategory model"""
|
"""Return the API url associated with the PartCategory model"""
|
||||||
|
@ -75,6 +75,7 @@ class CategorySerializer(InvenTreeModelSerializer):
|
|||||||
'pathstring',
|
'pathstring',
|
||||||
'starred',
|
'starred',
|
||||||
'url',
|
'url',
|
||||||
|
'icon',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -88,6 +89,7 @@ class CategoryTree(InvenTreeModelSerializer):
|
|||||||
'pk',
|
'pk',
|
||||||
'name',
|
'name',
|
||||||
'parent',
|
'parent',
|
||||||
|
'icon',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{% extends "part/part_app_base.html" %}
|
{% extends "part/part_app_base.html" %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
{% load inventree_extras %}
|
||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
{% include 'part/category_sidebar.html' %}
|
{% include 'part/category_sidebar.html' %}
|
||||||
@ -12,7 +13,12 @@
|
|||||||
|
|
||||||
{% block heading %}
|
{% block heading %}
|
||||||
{% if category %}
|
{% if category %}
|
||||||
{% trans "Part Category" %}: {{ category.name }}
|
{% trans "Part Category" %}:
|
||||||
|
{% settings_value "PART_CATEGORY_DEFAULT_ICON" as default_icon %}
|
||||||
|
{% if category.icon or default_icon %}
|
||||||
|
<span class="{{ category.icon|default:default_icon }}"></span>
|
||||||
|
{% endif %}
|
||||||
|
{{ category.name }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans "Parts" %}
|
{% trans "Parts" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -288,7 +294,8 @@
|
|||||||
node.href = `/part/category/${node.pk}/`;
|
node.href = `/part/category/${node.pk}/`;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
},
|
||||||
|
defaultIcon: global_settings.PART_CATEGORY_DEFAULT_ICON,
|
||||||
});
|
});
|
||||||
|
|
||||||
onPanelLoad('subcategories', function() {
|
onPanelLoad('subcategories', function() {
|
||||||
|
18
InvenTree/stock/migrations/0083_stocklocation_icon.py
Normal file
18
InvenTree/stock/migrations/0083_stocklocation_icon.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.15 on 2022-08-15 08:38
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('stock', '0082_alter_stockitem_link'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='stocklocation',
|
||||||
|
name='icon',
|
||||||
|
field=models.CharField(blank=True, help_text='Icon (optional)', max_length=100, verbose_name='Icon'),
|
||||||
|
),
|
||||||
|
]
|
@ -78,6 +78,13 @@ class StockLocation(MetadataMixin, InvenTreeTree):
|
|||||||
"""Return API url."""
|
"""Return API url."""
|
||||||
return reverse('api-location-list')
|
return reverse('api-location-list')
|
||||||
|
|
||||||
|
icon = models.CharField(
|
||||||
|
blank=True,
|
||||||
|
max_length=100,
|
||||||
|
verbose_name=_("Icon"),
|
||||||
|
help_text=_("Icon (optional)")
|
||||||
|
)
|
||||||
|
|
||||||
owner = models.ForeignKey(Owner, on_delete=models.SET_NULL, blank=True, null=True,
|
owner = models.ForeignKey(Owner, on_delete=models.SET_NULL, blank=True, null=True,
|
||||||
verbose_name=_('Owner'),
|
verbose_name=_('Owner'),
|
||||||
help_text=_('Select Owner'),
|
help_text=_('Select Owner'),
|
||||||
|
@ -570,6 +570,7 @@ class LocationTreeSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
|||||||
'pk',
|
'pk',
|
||||||
'name',
|
'name',
|
||||||
'parent',
|
'parent',
|
||||||
|
'icon',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -607,6 +608,7 @@ class LocationSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
|||||||
'pathstring',
|
'pathstring',
|
||||||
'items',
|
'items',
|
||||||
'owner',
|
'owner',
|
||||||
|
'icon',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,12 @@
|
|||||||
|
|
||||||
{% block heading %}
|
{% block heading %}
|
||||||
{% if location %}
|
{% if location %}
|
||||||
{% trans "Stock Location" %}: {{ location.name }}
|
{% trans "Stock Location" %}:
|
||||||
|
{% settings_value "STOCK_LOCATION_DEFAULT_ICON" as default_icon %}
|
||||||
|
{% if location.icon or default_icon %}
|
||||||
|
<span class="{{ location.icon|default:default_icon }}"></span>
|
||||||
|
{% endif %}
|
||||||
|
{{ location.name }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% trans "Stock" %}
|
{% trans "Stock" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -380,7 +385,8 @@
|
|||||||
node.href = `/stock/location/${node.pk}/`;
|
node.href = `/stock/location/${node.pk}/`;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
},
|
||||||
|
defaultIcon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
});
|
});
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
<tr><td colspan='5'></td></tr>
|
<tr><td colspan='5'></td></tr>
|
||||||
{% include "InvenTree/settings/setting.html" with key="PART_INTERNAL_PRICE" %}
|
{% include "InvenTree/settings/setting.html" with key="PART_INTERNAL_PRICE" %}
|
||||||
{% include "InvenTree/settings/setting.html" with key="PART_BOM_USE_INTERNAL_PRICE" %}
|
{% include "InvenTree/settings/setting.html" with key="PART_BOM_USE_INTERNAL_PRICE" %}
|
||||||
|
<tr><td colspan='5'></td></tr>
|
||||||
|
{% include "InvenTree/settings/setting.html" with key="PART_CATEGORY_DEFAULT_ICON" icon="fa-icons" %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
{% include "InvenTree/settings/setting.html" with key="STOCK_ALLOW_EXPIRED_SALE" icon="fa-truck" %}
|
{% include "InvenTree/settings/setting.html" with key="STOCK_ALLOW_EXPIRED_SALE" icon="fa-truck" %}
|
||||||
{% include "InvenTree/settings/setting.html" with key="STOCK_ALLOW_EXPIRED_BUILD" icon="fa-tools" %}
|
{% include "InvenTree/settings/setting.html" with key="STOCK_ALLOW_EXPIRED_BUILD" icon="fa-tools" %}
|
||||||
{% include "InvenTree/settings/setting.html" with key="STOCK_OWNERSHIP_CONTROL" icon="fa-users" %}
|
{% include "InvenTree/settings/setting.html" with key="STOCK_OWNERSHIP_CONTROL" icon="fa-users" %}
|
||||||
|
{% include "InvenTree/settings/setting.html" with key="STOCK_LOCATION_DEFAULT_ICON" icon="fa-icons" %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -216,6 +216,7 @@ function enableBreadcrumbTree(options) {
|
|||||||
enableLinks: true,
|
enableLinks: true,
|
||||||
expandIcon: 'fas fa-chevron-right',
|
expandIcon: 'fas fa-chevron-right',
|
||||||
collapseIcon: 'fa fa-chevron-down',
|
collapseIcon: 'fa fa-chevron-down',
|
||||||
|
nodeIcon: options.defaultIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,11 @@ function categoryFields() {
|
|||||||
default_location: {},
|
default_location: {},
|
||||||
default_keywords: {
|
default_keywords: {
|
||||||
icon: 'fa-key',
|
icon: 'fa-key',
|
||||||
}
|
},
|
||||||
|
icon: {
|
||||||
|
help_text: `{% trans "Icon (optional) - Explore all available icons on" %} <a href="https://fontawesome.com/v5/search?s=solid" target="_blank" rel="noopener noreferrer">Font Awesome</a>.`,
|
||||||
|
placeholder: 'fas fa-tag',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1916,6 +1920,11 @@ function loadPartCategoryTable(table, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const icon = row.icon || global_settings.PART_CATEGORY_DEFAULT_ICON;
|
||||||
|
if (icon) {
|
||||||
|
html += `<span class="${icon} me-1"></span>`;
|
||||||
|
}
|
||||||
|
|
||||||
html += renderLink(
|
html += renderLink(
|
||||||
value,
|
value,
|
||||||
`/part/category/${row.pk}/`
|
`/part/category/${row.pk}/`
|
||||||
|
@ -114,6 +114,10 @@ function stockLocationFields(options={}) {
|
|||||||
name: {},
|
name: {},
|
||||||
description: {},
|
description: {},
|
||||||
owner: {},
|
owner: {},
|
||||||
|
icon: {
|
||||||
|
help_text: `{% trans "Icon (optional) - Explore all available icons on" %} <a href="https://fontawesome.com/v5/search?s=solid" target="_blank" rel="noopener noreferrer">Font Awesome</a>.`,
|
||||||
|
placeholder: 'fas fa-box',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.parent) {
|
if (options.parent) {
|
||||||
@ -2402,6 +2406,11 @@ function loadStockLocationTable(table, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const icon = row.icon || global_settings.STOCK_LOCATION_DEFAULT_ICON;
|
||||||
|
if (icon) {
|
||||||
|
html += `<span class="${icon} me-1"></span>`;
|
||||||
|
}
|
||||||
|
|
||||||
html += renderLink(
|
html += renderLink(
|
||||||
value,
|
value,
|
||||||
`/stock/location/${row.pk}/`
|
`/stock/location/${row.pk}/`
|
||||||
|
Loading…
Reference in New Issue
Block a user