1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 05:02:36 +01:00

Fix invoice item drag/drop sorting

This commit is contained in:
Hillel Coren 2017-07-27 10:08:36 +03:00
parent a9b13992e4
commit 0d53a5de2b
3 changed files with 57 additions and 44 deletions

View File

@ -858,19 +858,14 @@
@endif
@if (isset($tasks) && $tasks)
// move the blank invoice line item to the end
var blank = model.invoice().invoice_items.pop();
var tasks = {!! json_encode($tasks) !!};
for (var i=0; i<tasks.length; i++) {
var task = tasks[i];
var item = model.invoice().addItem();
var item = model.invoice().addItem(true);
item.notes(task.description);
item.qty(task.duration);
item.task_public_id(task.publicId);
item.invoice_item_type_id({{ INVOICE_ITEM_TYPE_TASK }});
}
model.invoice().invoice_items.push(blank);
model.invoice().has_tasks(true);
@endif
@ -878,7 +873,7 @@
model.expense_currency_id({{ isset($expenseCurrencyId) ? $expenseCurrencyId : 0 }});
// move the blank invoice line item to the end
var blank = model.invoice().invoice_items.pop();
var blank = model.invoice().invoice_items_without_tasks.pop();
var expenses = {!! $expenses !!}
for (var i=0; i<expenses.length; i++) {
@ -894,7 +889,7 @@
item.tax_rate2(expense.tax_rate2);
item.tax_name2(expense.tax_name2);
}
model.invoice().invoice_items.push(blank);
model.invoice().invoice_items_without_tasks.push(blank);
model.invoice().has_expenses(true);
@endif
@ -1509,23 +1504,25 @@
{
var hasEmptyStandard = false;
var hasEmptyTask = false;
for(var i=0; i<model.invoice().invoice_items().length; i++) {
var item = model.invoice().invoice_items()[i];
for (var i=0; i<model.invoice().invoice_items_without_tasks().length; i++) {
var item = model.invoice().invoice_items_without_tasks()[i];
if (item.isEmpty()) {
if (item.invoice_item_type_id() == {{ INVOICE_ITEM_TYPE_TASK }}) {
hasEmptyTask = true;
} else {
hasEmptyStandard = true;
}
hasEmptyStandard = true;
}
}
if (!hasEmptyStandard) {
model.invoice().addItem();
}
for (var i=0; i<model.invoice().invoice_items_with_tasks().length; i++) {
var item = model.invoice().invoice_items_with_tasks()[i];
if (item.isEmpty()) {
hasEmptyTask = true;
}
}
if (!hasEmptyTask) {
item = model.invoice().addItem();
item.invoice_item_type_id({{ INVOICE_ITEM_TYPE_TASK }});
model.invoice().addItem(true);
}
if (!silent) {

View File

@ -19,12 +19,12 @@
<th style="min-width:32px;" class="hide-border"></th>
</tr>
</thead>
<tbody data-bind="sortable: { data: {{ $isTasks ? 'invoice_items_with_tasks' : 'invoice_items_without_tasks' }}, afterMove: onDragged} {{ $isTasks ? ', visible: $root.hasTasks' : '' }}"
<tbody data-bind="sortable: { data: invoice_items_{{ $isTasks ? 'with_tasks' : 'without_tasks' }}, allowDrop: false, afterMove: onDragged} {{ $isTasks ? ', visible: $root.hasTasks' : '' }}"
{!! $isTasks ? 'style="display:none;border-spacing: 100px"' : '' !!}>
<tr data-bind="event: { mouseover: showActions, mouseout: hideActions }" class="sortable-row">
<td class="hide-border td-icon">
<i style="display:none" data-bind="visible: actionsVisible() &amp;&amp;
$parent.invoice_items().length > 1" class="fa fa-sort"></i>
$parent.invoice_items_{{ $isTasks ? 'with_tasks' : 'without_tasks' }}().length > 1" class="fa fa-sort"></i>
</td>
<td>
<div id="scrollable-dropdown-menu">

View File

@ -166,15 +166,15 @@ function ViewModel(data) {
}
});
self.hasTasksCached;
self.hasTasksCached = false;
self.hasTasks = ko.computed(function() {
if (self.hasTasksCached) {
return true;
}
invoice = self.invoice();
for (var i=0; i<invoice.invoice_items().length; ++i) {
for (var i=0; i<invoice.invoice_items_with_tasks().length; ++i) {
var item = invoice.invoice_items()[i];
if (! item.isEmpty() && item.invoice_item_type_id() == {{ INVOICE_ITEM_TYPE_TASK }}) {
if (! item.isEmpty()) {
self.hasTasksCached = true;
return true;
}
@ -229,7 +229,6 @@ function InvoiceModel(data) {
self.auto_bill = ko.observable(0);
self.client_enable_auto_bill = ko.observable(false);
self.invoice_status_id = ko.observable(0);
self.invoice_items = ko.observableArray();
self.documents = ko.observableArray();
self.expenses = ko.observableArray();
self.amount = ko.observable(0);
@ -246,17 +245,33 @@ function InvoiceModel(data) {
self.custom_text_value1 = ko.observable();
self.custom_text_value2 = ko.observable();
self.invoice_items_with_tasks = ko.observableArray();
self.invoice_items_without_tasks = ko.observableArray();
self.invoice_items = ko.computed({
read: function () {
return self.invoice_items_with_tasks().concat(self.invoice_items_without_tasks());
},
write: function(data) {
self.invoice_items_with_tasks.removeAll();
self.invoice_items_without_tasks.removeAll();
for (var i=0; i<data.length; i++) {
var item = new ItemModel(data[i]);
if (item.isTask()) {
self.invoice_items_with_tasks.push(item);
} else {
self.invoice_items_without_tasks.push(item);
}
}
},
owner: this
})
self.mapping = {
'client': {
create: function(options) {
return new ClientModel(options.data);
}
},
'invoice_items': {
create: function(options) {
return new ItemModel(options.data);
}
},
'documents': {
create: function(options) {
return new DocumentModel(options.data);
@ -269,7 +284,7 @@ function InvoiceModel(data) {
},
}
self.addItem = function() {
self.addItem = function(isTask) {
if (self.invoice_items().length >= {{ MAX_INVOICE_ITEMS }}) {
return false;
}
@ -277,7 +292,12 @@ function InvoiceModel(data) {
@if ($account->hide_quantity)
itemModel.qty(1);
@endif
self.invoice_items.push(itemModel);
if (isTask) {
itemModel.invoice_item_type_id({{ INVOICE_ITEM_TYPE_TASK }});
self.invoice_items_with_tasks.push(itemModel);
} else {
self.invoice_items_without_tasks.push(itemModel);
}
applyComboboxListeners();
return itemModel;
}
@ -329,7 +349,11 @@ function InvoiceModel(data) {
})
self.removeItem = function(item) {
self.invoice_items.remove(item);
if (item.isTask()) {
self.invoice_items_with_tasks.remove(item);
} else {
self.invoice_items_without_tasks.remove(item);
}
refreshPDF(true);
}
@ -568,18 +592,6 @@ function InvoiceModel(data) {
}
self.applyInclusivTax(taxRate);
}
self.invoice_items_with_tasks = ko.computed(function() {
return ko.utils.arrayFilter(self.invoice_items(), function(item) {
return item.invoice_item_type_id() == {{ INVOICE_ITEM_TYPE_TASK }};
});
});
self.invoice_items_without_tasks = ko.computed(function() {
return ko.utils.arrayFilter(self.invoice_items(), function(item) {
return item.invoice_item_type_id() != {{ INVOICE_ITEM_TYPE_TASK }};
});
});
}
function ClientModel(data) {
@ -769,6 +781,10 @@ function ItemModel(data) {
self.invoice_item_type_id = ko.observable({{ INVOICE_ITEM_TYPE_STANDARD }});
self.actionsVisible = ko.observable(false);
self.isTask = ko.computed(function() {
return self.invoice_item_type_id() == {{ INVOICE_ITEM_TYPE_TASK }};
});
this.tax1 = ko.computed({
read: function () {
return self.tax_rate1IsInclusive() + ' ' + self.tax_rate1() + ' ' + self.tax_name1();