2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-16 12:05:53 +00:00

Adds template and JS code for manipulation of contacts

- Display a table
- Create / edit / delete
This commit is contained in:
Oliver Walters
2023-03-14 20:44:08 +11:00
parent ab5e5cab69
commit 095c4d5d05
3 changed files with 306 additions and 19 deletions

View File

@ -1,6 +1,7 @@
{% extends "company/company_base.html" %} {% extends "company/company_base.html" %}
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
{% load inventree_extras %}
{% block sidebar %} {% block sidebar %}
{% include 'company/sidebar.html' %} {% include 'company/sidebar.html' %}
@ -163,6 +164,7 @@
</div> </div>
</div> </div>
{% if company.is_customer %}
<div class='panel panel-hidden' id='panel-assigned-stock'> <div class='panel panel-hidden' id='panel-assigned-stock'>
<div class='panel-heading'> <div class='panel-heading'>
<h4>{% trans "Assigned Stock" %}</h4> <h4>{% trans "Assigned Stock" %}</h4>
@ -175,9 +177,9 @@
</div> </div>
<table class='table table-striped table-condensed' id='assigned-stock-table' data-toolbar='#assigned-stock-button-toolbar'></table> <table class='table table-striped table-condensed' id='assigned-stock-table' data-toolbar='#assigned-stock-button-toolbar'></table>
</div> </div>
</div> </div>
{% endif %}
<div class='panel panel-hidden' id='panel-company-notes'> <div class='panel panel-hidden' id='panel-company-notes'>
<div class='panel-heading'> <div class='panel-heading'>
@ -194,6 +196,31 @@
</div> </div>
</div> </div>
<div class='panel panel-hidden' id='panel-company-contacts'>
<div class='panel-heading'>
<div class='d-flex flex-wrap'>
<h4>{% trans "Company Contacts" %}</h4>
{% include "spacer.html" %}
<div class='btn-group' role='group'>
{% if roles.purchase_order.add or roles.sales_order.add %}
<button class='btn btn-success' type='button' id='new-contact' title='{% trans "Add Contact" %}'>
<div class='fas fa-plus-circle'></div> {% trans "Add Contact" %}
</button>
{% endif %}
</div>
</div>
</div>
<div class='panel-content'>
<div id='contacts-button-toolbar'>
<div class='btn-group' role='group'>
{% include "filter_list.html" with id="contacts" %}
</div>
</div>
<table class='table table-striped table-condensed' id='contacts-table' data-toolbar='#contacts-button-toolbar'></table>
</div>
</div>
<div class='panel panel-hidden' id='panel-attachments'> <div class='panel panel-hidden' id='panel-attachments'>
<div class='panel-heading'> <div class='panel-heading'>
<div class='d-flex flex-wrap'> <div class='d-flex flex-wrap'>
@ -242,6 +269,27 @@
); );
}); });
// Callback function when the 'contacts' panel is loaded
onPanelLoad('company-contacts', function() {
loadContactTable('#contacts-table', {
params: {
company: {{ company.pk }},
},
allow_edit: {% js_bool roles.purchase_order.change %} || {% js_bool roles.sales_order.change %},
allow_delete: {% js_bool roles.purchase_order.delete %} || {% js_bool roles.sales_order.delete %},
});
$('#new-contact').click(function() {
createContact({
company: {{ company.pk }},
onSuccess: function() {
$('#contacts-table').bootstrapTable('refresh');
}
});
});
});
// Callback function when the 'notes' panel is loaded
onPanelLoad('company-notes', function() { onPanelLoad('company-notes', function() {
setupNotesField( setupNotesField(
@ -250,19 +298,24 @@
{ {
editable: true, editable: true,
} }
) );
}); });
loadStockTable($("#assigned-stock-table"), { {% if company.is_customer %}
params: { // Callback function when the 'assigned stock' panel is loaded
customer: {{ company.id }}, onPanelLoad('assigned-stock', function() {
part_detail: true, loadStockTable($("#assigned-stock-table"), {
location_detail: true, params: {
}, customer: {{ company.id }},
url: "{% url 'api-stock-list' %}", part_detail: true,
filterKey: "customerstock", location_detail: true,
filterTarget: '#filter-list-customerstock', },
url: "{% url 'api-stock-list' %}",
filterKey: "customerstock",
filterTarget: '#filter-list-customerstock',
});
}); });
{% endif %}
onPanelLoad('company-stock', function() { onPanelLoad('company-stock', function() {

View File

@ -22,6 +22,8 @@
{% trans "Assigned Stock Items" as text %} {% trans "Assigned Stock Items" as text %}
{% include "sidebar_item.html" with label='assigned-stock' text=text icon="fa-sign-out-alt" %} {% include "sidebar_item.html" with label='assigned-stock' text=text icon="fa-sign-out-alt" %}
{% endif %} {% endif %}
{% trans "Contacts" as text %}
{% include "sidebar_item.html" with label='company-contacts' text=text icon="fa-users" %}
{% trans "Notes" as text %} {% trans "Notes" as text %}
{% include "sidebar_item.html" with label='company-notes' text=text icon="fa-clipboard" %} {% include "sidebar_item.html" with label='company-notes' text=text icon="fa-clipboard" %}
{% trans "Attachments" as text %} {% trans "Attachments" as text %}

View File

@ -11,16 +11,20 @@
/* exported /* exported
createCompany, createCompany,
createContact,
createManufacturerPart, createManufacturerPart,
createSupplierPart, createSupplierPart,
createSupplierPartPriceBreak, createSupplierPartPriceBreak,
deleteContacts,
deleteManufacturerParts, deleteManufacturerParts,
deleteManufacturerPartParameters, deleteManufacturerPartParameters,
deleteSupplierParts, deleteSupplierParts,
duplicateSupplierPart, duplicateSupplierPart,
editCompany, editCompany,
editContact,
editSupplierPartPriceBreak, editSupplierPartPriceBreak,
loadCompanyTable, loadCompanyTable,
loadContactTable,
loadManufacturerPartTable, loadManufacturerPartTable,
loadManufacturerPartParameterTable, loadManufacturerPartParameterTable,
loadSupplierPartTable, loadSupplierPartTable,
@ -443,15 +447,15 @@ function createCompany(options={}) {
} }
/*
* Load company listing data into specified table.
*
* Args:
* - table: Table element on the page
* - url: Base URL for the API query
* - options: table options.
*/
function loadCompanyTable(table, url, options={}) { function loadCompanyTable(table, url, options={}) {
/*
* Load company listing data into specified table.
*
* Args:
* - table: Table element on the page
* - url: Base URL for the API query
* - options: table options.
*/
// Query parameters // Query parameters
var params = options.params || {}; var params = options.params || {};
@ -547,6 +551,234 @@ function loadCompanyTable(table, url, options={}) {
} }
/*
* Construct a set of form fields for the Contact model
*/
function contactFields(options={}) {
let fields = {
company: {
icon: 'fa-building',
},
name: {
icon: 'fa-user',
},
phone: {
icon: 'fa-phone'
},
email: {
icon: 'fa-at',
},
role: {
icon: 'fa-user-tag',
},
};
if (options.company) {
fields.company.value = options.company;
}
return fields;
}
/*
* Launches a form to create a new Contact
*/
function createContact(options={}) {
let fields = options.fields || contactFields(options);
constructForm('{% url "api-contact-list" %}', {
method: 'POST',
fields: fields,
title: '{% trans "Create New Contact" %}',
onSuccess: function(response) {
handleFormSuccess(response, options);
}
});
}
/*
* Launches a form to edit an existing Contact
*/
function editContact(pk, options={}) {
let fields = options.fields || contactFields(options);
constructForm(`/api/company/contact/${pk}/`, {
fields: fields,
title: '{% trans "Edit Contact" %}',
onSuccess: function(response) {
handleFormSuccess(respnose, options);
}
});
}
/*
* Launches a form to delete one (or more) contacts
*/
function deleteContacts(contacts, options={}) {
if (contacts.length == 0) {
return;
}
function renderContact(contact) {
return `
<tr>
<td>${contact.name}</td>
<td>${contact.email}</td>
<td>${contact.role}</td>
</tr>`;
}
let rows = '';
let ids = [];
contacts.forEach(function(contact) {
rows += renderContact(contact);
ids.push(contact.pk);
});
let html = `
<div class='alert alert-block alert-danger'>
{% trans "All selected contacts will be deleted" %}
</div>
<table class='table table-striped table-condensed'>
<tr>
<th>{% trans "Name" %}</th>
<th>{% trans "Email" %}</th>
<th>{% trans "Role" %}</th>
</tr>
${rows}
</table>`;
constructForm('{% url "api-contact-list" %}', {
method: 'DELETE',
multi_delete: true,
title: '{% trans "Delete Contacts" %}',
preFormContent: html,
form_data: {
items: ids,
},
onSuccess: function(response) {
handleFormSuccess(response, options);
}
});
}
/*
* Load table listing company contacts
*/
function loadContactTable(table, options={}) {
var params = options.params || {};
var filters = loadTableFilters('contact');
for (var key in params) {
filters[key] = params[key];
}
setupFilterList('contact', $(table), '#filter-list-contacts');
$(table).inventreeTable({
url: '{% url "api-contact-list" %}',
queryParams: filters,
original: params,
idField: 'pk',
uniqueId: 'pk',
sidePagination: 'server',
formatNoMatches: function() {
return '{% trans "No contacts found" %}';
},
showColumns: true,
name: 'contacts',
columns: [
{
field: 'name',
title: '{% trans "Name" %}',
sortable: true,
switchable: false,
},
{
field: 'phone',
title: '{% trans "Phone Number" %}',
sortable: false,
switchable: true,
},
{
field: 'email',
title: '{% trans "Email Address" %}',
sortable: false,
switchable: true,
},
{
field: 'role',
title: '{% trans "Role" %}',
sortable: false,
switchable: false,
},
{
field: 'actions',
title: '',
sortable: false,
switchable: false,
visible: options.allow_edit || options.allow_delete,
formatter: function(value, row) {
var pk = row.pk;
var html = `<div class='btn-group float-right' role='group'>`;
if (options.allow_edit) {
html += makeIconButton('fa-edit icon-blue', 'btn-contact-edit', pk, '{% trans "Edit Contact" %}');
}
if (options.allow_delete) {
html += makeIconButton('fa-trash-alt icon-red', 'btn-contact-delete', pk, '{% trans "Delete Contact" %}');
}
html += '</div>';
return html;
}
}
],
onPostBody: function() {
// Edit button callback
if (options.allow_edit) {
$(table).find('.btn-contact-edit').click(function() {
var pk = $(this).attr('pk');
editContact(pk, {
onSuccess: function() {
$(table).bootstrapTable('refresh');
}
});
});
}
// Delete button callback
if (options.allow_delete) {
$(table).find('.btn-contact-delete').click(function() {
var pk = $(this).attr('pk');
var row = $(table).bootstrapTable('getRowByUniqueId', pk);
if (row && row.pk) {
deleteContacts([row], {
onSuccess: function() {
$(table).bootstrapTable('refresh');
}
});
}
});
}
}
});
}
/* Delete one or more ManufacturerPart objects from the database. /* Delete one or more ManufacturerPart objects from the database.
* - User will be provided with a modal form, showing all the parts to be deleted. * - User will be provided with a modal form, showing all the parts to be deleted.
* - Delete operations are performed sequentialy, not simultaneously * - Delete operations are performed sequentialy, not simultaneously