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:
@ -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() {
|
||||||
|
|
||||||
|
@ -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 %}
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user