2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-15 19:45:46 +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" %}
{% load static %}
{% load i18n %}
{% load inventree_extras %}
{% block sidebar %}
{% include 'company/sidebar.html' %}
@ -163,6 +164,7 @@
</div>
</div>
{% if company.is_customer %}
<div class='panel panel-hidden' id='panel-assigned-stock'>
<div class='panel-heading'>
<h4>{% trans "Assigned Stock" %}</h4>
@ -175,9 +177,9 @@
</div>
<table class='table table-striped table-condensed' id='assigned-stock-table' data-toolbar='#assigned-stock-button-toolbar'></table>
</div>
</div>
{% endif %}
<div class='panel panel-hidden' id='panel-company-notes'>
<div class='panel-heading'>
@ -194,6 +196,31 @@
</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-heading'>
<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() {
setupNotesField(
@ -250,9 +298,12 @@
{
editable: true,
}
)
);
});
{% if company.is_customer %}
// Callback function when the 'assigned stock' panel is loaded
onPanelLoad('assigned-stock', function() {
loadStockTable($("#assigned-stock-table"), {
params: {
customer: {{ company.id }},
@ -263,6 +314,8 @@
filterKey: "customerstock",
filterTarget: '#filter-list-customerstock',
});
});
{% endif %}
onPanelLoad('company-stock', function() {

View File

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

View File

@ -11,16 +11,20 @@
/* exported
createCompany,
createContact,
createManufacturerPart,
createSupplierPart,
createSupplierPartPriceBreak,
deleteContacts,
deleteManufacturerParts,
deleteManufacturerPartParameters,
deleteSupplierParts,
duplicateSupplierPart,
editCompany,
editContact,
editSupplierPartPriceBreak,
loadCompanyTable,
loadContactTable,
loadManufacturerPartTable,
loadManufacturerPartParameterTable,
loadSupplierPartTable,
@ -443,7 +447,6 @@ function createCompany(options={}) {
}
function loadCompanyTable(table, url, options={}) {
/*
* Load company listing data into specified table.
*
@ -452,6 +455,7 @@ function loadCompanyTable(table, url, options={}) {
* - url: Base URL for the API query
* - options: table options.
*/
function loadCompanyTable(table, url, options={}) {
// Query parameters
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.
* - User will be provided with a modal form, showing all the parts to be deleted.
* - Delete operations are performed sequentialy, not simultaneously