mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Feature/Tree picker (#5595)
* Show only the current modal over the backdrop, move others behind * Added initial draft for tree picker * Added filters to tree picker * Added tree picker to more location fields * Fixed bug with missing input group and filters side effect * Added tree picker to part category inputs * Added missing picker for part category parent input * Fixed disabled items * Fix js linting errors * trigger: ci * Bump api_version.py * Update api_version.py
This commit is contained in:
parent
3d8e3f1625
commit
9b4e1743c7
@ -2,11 +2,14 @@
|
|||||||
|
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 135
|
INVENTREE_API_VERSION = 136
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
||||||
|
|
||||||
|
v136 -> 2023-09-23 : https://github.com/inventree/InvenTree/pull/5595
|
||||||
|
- Adds structural to StockLocation and PartCategory tree endpoints
|
||||||
|
|
||||||
v135 -> 2023-09-19 : https://github.com/inventree/InvenTree/pull/5569
|
v135 -> 2023-09-19 : https://github.com/inventree/InvenTree/pull/5569
|
||||||
- Adds location path detail to StockLocation and StockItem API endpoints
|
- Adds location path detail to StockLocation and StockItem API endpoints
|
||||||
- Adds category path detail to PartCategory and Part API endpoints
|
- Adds category path detail to PartCategory and Part API endpoints
|
||||||
|
@ -1097,3 +1097,7 @@ a {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.large-treeview-icon {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
@ -113,6 +113,7 @@ class CategoryTree(InvenTree.serializers.InvenTreeModelSerializer):
|
|||||||
'name',
|
'name',
|
||||||
'parent',
|
'parent',
|
||||||
'icon',
|
'icon',
|
||||||
|
'structural',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -239,8 +239,17 @@
|
|||||||
generateStocktakeReport({
|
generateStocktakeReport({
|
||||||
category: {
|
category: {
|
||||||
{% if category %}value: {{ category.pk }},{% endif %}
|
{% if category %}value: {{ category.pk }},{% endif %}
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-part-category-tree" %}',
|
||||||
|
default_icon: global_settings.PART_CATEGORY_DEFAULT_ICON,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
location: {
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
location: {},
|
|
||||||
generate_report: {},
|
generate_report: {},
|
||||||
update_parts: {},
|
update_parts: {},
|
||||||
});
|
});
|
||||||
|
@ -436,7 +436,12 @@
|
|||||||
part: {
|
part: {
|
||||||
value: {{ part.pk }}
|
value: {{ part.pk }}
|
||||||
},
|
},
|
||||||
location: {},
|
location: {
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
|
},
|
||||||
generate_report: {
|
generate_report: {
|
||||||
value: false,
|
value: false,
|
||||||
},
|
},
|
||||||
|
@ -775,6 +775,7 @@ class LocationTreeSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
|||||||
'name',
|
'name',
|
||||||
'parent',
|
'parent',
|
||||||
'icon',
|
'icon',
|
||||||
|
'structural',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -650,6 +650,10 @@ $("#stock-return-from-customer").click(function() {
|
|||||||
{% if item.part.default_location %}
|
{% if item.part.default_location %}
|
||||||
value: {{ item.part.default_location.pk }},
|
value: {{ item.part.default_location.pk }},
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
notes: {
|
notes: {
|
||||||
icon: 'fa-sticky-note',
|
icon: 'fa-sticky-note',
|
||||||
|
@ -238,9 +238,18 @@
|
|||||||
{% if stocktake_enable and roles.stocktake.add %}
|
{% if stocktake_enable and roles.stocktake.add %}
|
||||||
$('#location-stocktake').click(function() {
|
$('#location-stocktake').click(function() {
|
||||||
generateStocktakeReport({
|
generateStocktakeReport({
|
||||||
category: {},
|
category: {
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-part-category-tree" %}',
|
||||||
|
default_icon: global_settings.PART_CATEGORY_DEFAULT_ICON,
|
||||||
|
},
|
||||||
|
},
|
||||||
location: {
|
location: {
|
||||||
{% if location %}value: {{ location.pk }},{% endif %}
|
{% if location %}value: {{ location.pk }},{% endif %}
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
generate_report: {},
|
generate_report: {},
|
||||||
update_parts: {},
|
update_parts: {},
|
||||||
|
@ -308,6 +308,10 @@ onPanelLoad('category', function() {
|
|||||||
parameter_template: {},
|
parameter_template: {},
|
||||||
category: {
|
category: {
|
||||||
icon: 'fa-sitemap',
|
icon: 'fa-sitemap',
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-part-category-tree" %}',
|
||||||
|
default_icon: global_settings.PART_CATEGORY_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
default_value: {},
|
default_value: {},
|
||||||
},
|
},
|
||||||
@ -368,6 +372,10 @@ onPanelLoad('category', function() {
|
|||||||
category: {
|
category: {
|
||||||
icon: 'fa-sitemap',
|
icon: 'fa-sitemap',
|
||||||
value: pk,
|
value: pk,
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-part-category-tree" %}',
|
||||||
|
default_icon: global_settings.PART_CATEGORY_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
default_value: {},
|
default_value: {},
|
||||||
},
|
},
|
||||||
@ -453,8 +461,18 @@ onPanelLoad('stocktake', function() {
|
|||||||
$('#btn-generate-stocktake').click(function() {
|
$('#btn-generate-stocktake').click(function() {
|
||||||
generateStocktakeReport({
|
generateStocktakeReport({
|
||||||
part: {},
|
part: {},
|
||||||
category: {},
|
category: {
|
||||||
location: {},
|
tree_picker: {
|
||||||
|
url: '{% url "api-part-category-tree" %}',
|
||||||
|
default_icon: global_settings.PART_CATEGORY_DEFAULT_ICON,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
location: {
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
|
},
|
||||||
generate_report: {},
|
generate_report: {},
|
||||||
update_parts: {},
|
update_parts: {},
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
addSidebarHeader,
|
addSidebarHeader,
|
||||||
addSidebarItem,
|
addSidebarItem,
|
||||||
addSidebarLink,
|
addSidebarLink,
|
||||||
|
generateTreeStructure,
|
||||||
enableBreadcrumbTree,
|
enableBreadcrumbTree,
|
||||||
enableSidebar,
|
enableSidebar,
|
||||||
onPanelLoad,
|
onPanelLoad,
|
||||||
@ -146,6 +147,59 @@ function enableSidebar(label, options={}) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate nested tree structure for jquery treeview from flattened list of
|
||||||
|
* tree nodes with refs to their parents
|
||||||
|
* @param {Array} data flat tree data as list of objects
|
||||||
|
* @param {Object} options custom options
|
||||||
|
* @param {Function} options.processNode Function that can change the treeview node obj
|
||||||
|
* @param {Number} options.selected pk of the node that should be preselected
|
||||||
|
*/
|
||||||
|
function generateTreeStructure(data, options) {
|
||||||
|
const nodes = {};
|
||||||
|
const roots = [];
|
||||||
|
let node = null;
|
||||||
|
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
node = data[i];
|
||||||
|
nodes[node.pk] = node;
|
||||||
|
node.selectable = false;
|
||||||
|
|
||||||
|
node.state = {
|
||||||
|
expanded: node.pk == options.selected,
|
||||||
|
selected: node.pk == options.selected,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options.processNode) {
|
||||||
|
node = options.processNode(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
node = data[i];
|
||||||
|
|
||||||
|
if (node.parent != null) {
|
||||||
|
if (nodes[node.parent].nodes) {
|
||||||
|
nodes[node.parent].nodes.push(node);
|
||||||
|
} else {
|
||||||
|
nodes[node.parent].nodes = [node];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.state.expanded) {
|
||||||
|
while (node.parent != null) {
|
||||||
|
nodes[node.parent].state.expanded = true;
|
||||||
|
node = nodes[node.parent];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
roots.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return roots;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable support for breadcrumb tree navigation on this page
|
* Enable support for breadcrumb tree navigation on this page
|
||||||
*/
|
*/
|
||||||
@ -168,47 +222,7 @@ function enableBreadcrumbTree(options) {
|
|||||||
|
|
||||||
// Data are returned from the InvenTree server as a flattened list;
|
// Data are returned from the InvenTree server as a flattened list;
|
||||||
// We need to convert this into a tree structure
|
// We need to convert this into a tree structure
|
||||||
|
const roots = generateTreeStructure(data, options);
|
||||||
var nodes = {};
|
|
||||||
var roots = [];
|
|
||||||
var node = null;
|
|
||||||
|
|
||||||
for (var i = 0; i < data.length; i++) {
|
|
||||||
node = data[i];
|
|
||||||
nodes[node.pk] = node;
|
|
||||||
node.selectable = false;
|
|
||||||
|
|
||||||
if (options.processNode) {
|
|
||||||
node = options.processNode(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
node.state = {
|
|
||||||
expanded: node.pk == options.selected,
|
|
||||||
selected: node.pk == options.selected,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < data.length; i++) {
|
|
||||||
node = data[i];
|
|
||||||
|
|
||||||
if (node.parent != null) {
|
|
||||||
if (nodes[node.parent].nodes) {
|
|
||||||
nodes[node.parent].nodes.push(node);
|
|
||||||
} else {
|
|
||||||
nodes[node.parent].nodes = [node];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.state.expanded) {
|
|
||||||
while (node.parent != null) {
|
|
||||||
nodes[node.parent].state.expanded = true;
|
|
||||||
node = nodes[node.parent];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
roots.push(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#breadcrumb-tree').treeview({
|
$('#breadcrumb-tree').treeview({
|
||||||
data: roots,
|
data: roots,
|
||||||
|
@ -605,6 +605,10 @@ function completeBuildOutputs(build_id, outputs, options={}) {
|
|||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
},
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
notes: {
|
notes: {
|
||||||
icon: 'fa-sticky-note',
|
icon: 'fa-sticky-note',
|
||||||
@ -734,7 +738,11 @@ function scrapBuildOutputs(build_id, outputs, options={}) {
|
|||||||
location: {
|
location: {
|
||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
}
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
notes: {},
|
notes: {},
|
||||||
discard_allocations: {},
|
discard_allocations: {},
|
||||||
@ -1926,7 +1934,11 @@ function autoAllocateStockToBuild(build_id, bom_items=[], options={}) {
|
|||||||
value: options.location,
|
value: options.location,
|
||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
}
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
exclude_location: {},
|
exclude_location: {},
|
||||||
interchangeable: {
|
interchangeable: {
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
showMessage,
|
showMessage,
|
||||||
showModalSpinner,
|
showModalSpinner,
|
||||||
toBool,
|
toBool,
|
||||||
|
showQuestionDialog,
|
||||||
|
generateTreeStructure,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* exported
|
/* exported
|
||||||
@ -2022,6 +2024,94 @@ function initializeRelatedField(field, fields, options={}) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(field.tree_picker) {
|
||||||
|
// construct button
|
||||||
|
const button = $(`<button class="input-group-text px-2"><i class="fas fa-external-link-alt"></i></button>`);
|
||||||
|
|
||||||
|
// insert open tree picker button after select
|
||||||
|
select.parent().find(".select2").after(button);
|
||||||
|
|
||||||
|
// save copy of filters, because of possible side effects
|
||||||
|
const filters = field.filters ? { ...field.filters } : {};
|
||||||
|
|
||||||
|
button.on("click", () => {
|
||||||
|
const tree_id = `${name}_tree`;
|
||||||
|
|
||||||
|
const title = '{% trans "Select" %}' + " " + options.actions[name].label;
|
||||||
|
const content = `
|
||||||
|
<div class="mb-1">
|
||||||
|
<div class="input-group mb-2">
|
||||||
|
<input class="form-control" type="text" id="${name}_tree_search" placeholder="{% trans "Search" %} ${options.actions[name].label}..." />
|
||||||
|
<button class="input-group-text" id="${name}_tree_search_btn"><i class="fas fa-search"></i></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="${tree_id}" style="height: 65vh; overflow-y: auto;">
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<div class="spinner-border" role="status"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
showQuestionDialog(title, content, {
|
||||||
|
accept_text: '{% trans "Select" %}',
|
||||||
|
accept: () => {
|
||||||
|
const selectedNode = $(`#${tree_id}`).treeview('getSelected');
|
||||||
|
if(selectedNode.length > 0) {
|
||||||
|
const url = `${field.api_url}/${selectedNode[0].pk}/`.replace('//', '/');
|
||||||
|
|
||||||
|
inventreeGet(url, field.filters || {}, {
|
||||||
|
success: function(data) {
|
||||||
|
setRelatedFieldData(name, data, options);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
inventreeGet(field.tree_picker.url, {}, {
|
||||||
|
success: (data) => {
|
||||||
|
const current_value = getFormFieldValue(name, field, options);
|
||||||
|
|
||||||
|
const rootNodes = generateTreeStructure(data, {
|
||||||
|
selected: current_value,
|
||||||
|
processNode: (node) => {
|
||||||
|
node.selectable = true;
|
||||||
|
node.text = node.name;
|
||||||
|
|
||||||
|
// disable this node, if it doesn't match the filter criteria
|
||||||
|
for (const [k, v] of Object.entries(filters)) {
|
||||||
|
if (k in node && node[k] !== v) {
|
||||||
|
node.selectable = false;
|
||||||
|
node.color = "grey";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(`#${tree_id}`).treeview({
|
||||||
|
data: rootNodes,
|
||||||
|
expandIcon: 'fas fa-plus-square large-treeview-icon',
|
||||||
|
collapseIcon: 'fa fa-minus-square large-treeview-icon',
|
||||||
|
nodeIcon: field.tree_picker.defaultIcon,
|
||||||
|
color: "black",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(`#${name}_tree_search_btn`).on("click", () => {
|
||||||
|
const searchValue = $(`#${name}_tree_search`).val();
|
||||||
|
$(`#${tree_id}`).treeview("search", [searchValue, {
|
||||||
|
ignoreCase: true,
|
||||||
|
exactMatch: false,
|
||||||
|
revealResults: true,
|
||||||
|
}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2244,7 +2334,7 @@ function constructField(name, parameters, options={}) {
|
|||||||
html += `<div class='controls'>`;
|
html += `<div class='controls'>`;
|
||||||
|
|
||||||
// Does this input deserve "extra" decorators?
|
// Does this input deserve "extra" decorators?
|
||||||
var extra = (parameters.icon != null) || (parameters.prefix != null) || (parameters.prefixRaw != null);
|
var extra = (parameters.icon != null) || (parameters.prefix != null) || (parameters.prefixRaw != null) || (parameters.tree_picker != null);
|
||||||
|
|
||||||
// Some fields can have 'clear' inputs associated with them
|
// Some fields can have 'clear' inputs associated with them
|
||||||
if (!parameters.required && !parameters.read_only) {
|
if (!parameters.required && !parameters.read_only) {
|
||||||
@ -2265,7 +2355,7 @@ function constructField(name, parameters, options={}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (extra) {
|
if (extra) {
|
||||||
html += `<div class='input-group'>`;
|
html += `<div class='input-group flex-nowrap'>`;
|
||||||
|
|
||||||
if (parameters.prefix) {
|
if (parameters.prefix) {
|
||||||
html += `<span class='input-group-text'>${parameters.prefix}</span>`;
|
html += `<span class='input-group-text'>${parameters.prefix}</span>`;
|
||||||
@ -2282,9 +2372,9 @@ function constructField(name, parameters, options={}) {
|
|||||||
|
|
||||||
if (!parameters.required && !options.hideClearButton) {
|
if (!parameters.required && !options.hideClearButton) {
|
||||||
html += `
|
html += `
|
||||||
<span class='input-group-text form-clear' id='clear_${field_name}' title='{% trans "Clear input" %}'>
|
<button class='input-group-text form-clear' id='clear_${field_name}' title='{% trans "Clear input" %}'>
|
||||||
<span class='icon-red fas fa-backspace'></span>
|
<span class='icon-red fas fa-backspace'></span>
|
||||||
</span>`;
|
</button>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
html += `</div>`; // input-group
|
html += `</div>`; // input-group
|
||||||
|
@ -44,6 +44,9 @@ function createNewModal(options={}) {
|
|||||||
if (modal_id >= id) {
|
if (modal_id >= id) {
|
||||||
id = modal_id + 1;
|
id = modal_id + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// move all other modals behind the backdrops
|
||||||
|
$(this).css('z-index', 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
var submitClass = options.submitClass || 'primary';
|
var submitClass = options.submitClass || 'primary';
|
||||||
@ -125,6 +128,9 @@ function createNewModal(options={}) {
|
|||||||
// Automatically remove the modal when it is deleted!
|
// Automatically remove the modal when it is deleted!
|
||||||
$(modal_name).on('hidden.bs.modal', function() {
|
$(modal_name).on('hidden.bs.modal', function() {
|
||||||
$(modal_name).remove();
|
$(modal_name).remove();
|
||||||
|
|
||||||
|
// restore all modals before backdrop
|
||||||
|
$('.inventree-modal').last().css("z-index", 10000);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Capture "enter" key input
|
// Capture "enter" key input
|
||||||
|
@ -128,6 +128,10 @@ function partFields(options={}) {
|
|||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
},
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-part-category-tree" %}',
|
||||||
|
default_icon: global_settings.PART_CATEGORY_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
name: {},
|
name: {},
|
||||||
IPN: {},
|
IPN: {},
|
||||||
@ -147,7 +151,11 @@ function partFields(options={}) {
|
|||||||
icon: 'fa-sitemap',
|
icon: 'fa-sitemap',
|
||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
}
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
default_supplier: {
|
default_supplier: {
|
||||||
icon: 'fa-building',
|
icon: 'fa-building',
|
||||||
@ -296,6 +304,10 @@ function categoryFields(options={}) {
|
|||||||
parent: {
|
parent: {
|
||||||
help_text: '{% trans "Parent part category" %}',
|
help_text: '{% trans "Parent part category" %}',
|
||||||
required: false,
|
required: false,
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-part-category-tree" %}',
|
||||||
|
default_icon: global_settings.PART_CATEGORY_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
name: {},
|
name: {},
|
||||||
description: {},
|
description: {},
|
||||||
@ -303,7 +315,11 @@ function categoryFields(options={}) {
|
|||||||
icon: 'fa-sitemap',
|
icon: 'fa-sitemap',
|
||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
}
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
default_keywords: {
|
default_keywords: {
|
||||||
icon: 'fa-key',
|
icon: 'fa-key',
|
||||||
@ -2185,7 +2201,12 @@ function setPartCategory(data, options={}) {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
preFormContent: html,
|
preFormContent: html,
|
||||||
fields: {
|
fields: {
|
||||||
category: {},
|
category: {
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-part-category-tree" %}',
|
||||||
|
default_icon: global_settings.PART_CATEGORY_DEFAULT_ICON,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
processBeforeUpload: function(data) {
|
processBeforeUpload: function(data) {
|
||||||
data.parts = parts;
|
data.parts = parts;
|
||||||
|
@ -1306,7 +1306,11 @@ function receivePurchaseOrderItems(order_id, line_items, options={}) {
|
|||||||
location: {
|
location: {
|
||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
}
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
preFormContent: html,
|
preFormContent: html,
|
||||||
|
@ -547,7 +547,11 @@ function receiveReturnOrderItems(order_id, line_items, options={}) {
|
|||||||
location: {
|
location: {
|
||||||
filters: {
|
filters: {
|
||||||
strucutral: false,
|
strucutral: false,
|
||||||
}
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
confirm: true,
|
confirm: true,
|
||||||
|
@ -136,6 +136,10 @@ function stockLocationFields(options={}) {
|
|||||||
parent: {
|
parent: {
|
||||||
help_text: '{% trans "Parent stock location" %}',
|
help_text: '{% trans "Parent stock location" %}',
|
||||||
required: false,
|
required: false,
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
name: {},
|
name: {},
|
||||||
description: {},
|
description: {},
|
||||||
@ -323,6 +327,10 @@ function stockItemFields(options={}) {
|
|||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
},
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
quantity: {
|
quantity: {
|
||||||
help_text: '{% trans "Enter initial quantity for this stock item" %}',
|
help_text: '{% trans "Enter initial quantity for this stock item" %}',
|
||||||
@ -878,7 +886,11 @@ function mergeStockItems(items, options={}) {
|
|||||||
icon: 'fa-sitemap',
|
icon: 'fa-sitemap',
|
||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
}
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
notes: {
|
notes: {
|
||||||
icon: 'fa-sticky-note',
|
icon: 'fa-sticky-note',
|
||||||
@ -3095,7 +3107,11 @@ function uninstallStockItem(installed_item_id, options={}) {
|
|||||||
icon: 'fa-sitemap',
|
icon: 'fa-sitemap',
|
||||||
filters: {
|
filters: {
|
||||||
structural: false,
|
structural: false,
|
||||||
}
|
},
|
||||||
|
tree_picker: {
|
||||||
|
url: '{% url "api-location-tree" %}',
|
||||||
|
default_icon: global_settings.STOCK_LOCATION_DEFAULT_ICON,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
note: {
|
note: {
|
||||||
icon: 'fa-sticky-note',
|
icon: 'fa-sticky-note',
|
||||||
|
Loading…
Reference in New Issue
Block a user