mirror of https://github.com/itflow-org/itflow
Added SortableJS Library, and updated Invoice, Quote and Recurring to use it. Added Grab Bar Icons next to action buttons. Will now sort in Mobile much more efficiently, update ajax vars for recurring invoice
This commit is contained in:
parent
60fe02bb47
commit
19b809b699
4
ajax.php
4
ajax.php
|
|
@ -586,13 +586,13 @@ if (isset($_POST['update_recurring_invoice_items_order'])) {
|
|||
enforceUserPermission('module_sales', 2);
|
||||
|
||||
$positions = $_POST['positions'];
|
||||
$recurring_id = intval($_POST['recurring_id']);
|
||||
$recurring_invoice_id = intval($_POST['recurring_invoice_id']);
|
||||
|
||||
foreach ($positions as $position) {
|
||||
$id = intval($position['id']);
|
||||
$order = intval($position['order']);
|
||||
|
||||
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = $order WHERE item_recurring_id = $recurring_id AND item_id = $id");
|
||||
mysqli_query($mysqli, "UPDATE invoice_items SET item_order = $order WHERE item_recurring_invoice_id = $recurring_invoice_id AND item_id = $id");
|
||||
}
|
||||
|
||||
// return a response
|
||||
|
|
|
|||
|
|
@ -20,10 +20,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
.grab-cursor {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.grab-cursor:active {
|
||||
cursor: grabbing;
|
||||
button.drag-handle {
|
||||
cursor: grab !important;
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
}
|
||||
button.drag-handle:active {
|
||||
cursor: grabbing !important;
|
||||
}
|
||||
86
invoice.php
86
invoice.php
|
|
@ -165,6 +165,7 @@ if (isset($_GET['invoice_id'])) {
|
|||
|
||||
|
||||
?>
|
||||
|
||||
<link rel="stylesheet" href="plugins/dragula/dragula.min.css">
|
||||
|
||||
<ol class="breadcrumb d-print-none">
|
||||
|
|
@ -381,26 +382,34 @@ if (isset($_GET['invoice_id'])) {
|
|||
<tr data-item-id="<?php echo $item_id; ?>">
|
||||
<td class="d-print-none">
|
||||
<?php if ($invoice_status !== "Paid" && $invoice_status !== "Cancelled") { ?>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#"
|
||||
data-toggle="ajax-modal"
|
||||
data-ajax-url="ajax/ajax_item_edit.php"
|
||||
data-ajax-id="<?php echo $item_id; ?>"
|
||||
>
|
||||
<i class="fa fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_invoice_item=<?php echo $item_id; ?>"><i class="fa fa-fw fa-trash mr-2"></i>Delete</a>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-sm btn-light drag-handle">
|
||||
<i class="fas fa-bars text-muted"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#"
|
||||
data-toggle="ajax-modal"
|
||||
data-ajax-url="ajax/ajax_item_edit.php"
|
||||
data-ajax-id="<?php echo $item_id; ?>"
|
||||
>
|
||||
<i class="fa fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_invoice_item=<?php echo $item_id; ?>"><i class="fa fa-fw fa-trash mr-2"></i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
</td>
|
||||
<td class="grab-cursor"><?php echo $item_name; ?></td>
|
||||
<td><?php echo $item_name; ?></td>
|
||||
<td><?php echo nl2br($item_description); ?></td>
|
||||
<td class="text-center"><?php echo number_format($item_quantity, 2); ?></td>
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_price, $invoice_currency_code); ?></td>
|
||||
|
|
@ -1178,38 +1187,23 @@ require_once "includes/footer.php";
|
|||
}
|
||||
</script>
|
||||
|
||||
<script src="plugins/dragula/dragula.min.js"></script>
|
||||
<script src="plugins/SortableJS/Sortable.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var container = $('table#items tbody')[0];
|
||||
new Sortable(document.querySelector('table#items tbody'), {
|
||||
handle: '.drag-handle',
|
||||
animation: 150,
|
||||
onEnd: function (evt) {
|
||||
const rows = document.querySelectorAll('table#items tbody tr');
|
||||
const positions = Array.from(rows).map((row, index) => ({
|
||||
id: row.dataset.itemId,
|
||||
order: index
|
||||
}));
|
||||
|
||||
dragula([container])
|
||||
.on('drop', function (el, target, source, sibling) {
|
||||
// Handle the drop event to update the order in the database
|
||||
var rows = $(container).children();
|
||||
var positions = rows.map(function(index, row) {
|
||||
return {
|
||||
id: $(row).data('itemId'),
|
||||
order: index
|
||||
};
|
||||
}).get();
|
||||
|
||||
// Send the new order to the server
|
||||
$.ajax({
|
||||
url: 'ajax.php',
|
||||
method: 'POST',
|
||||
data: {
|
||||
update_invoice_items_order: true,
|
||||
invoice_id: <?php echo $invoice_id; ?>,
|
||||
positions: positions
|
||||
},
|
||||
success: function(data) {
|
||||
// Handle success
|
||||
},
|
||||
error: function(error) {
|
||||
console.error('Error updating order:', error);
|
||||
}
|
||||
});
|
||||
$.post('ajax.php', {
|
||||
update_invoice_items_order: true,
|
||||
invoice_id: <?php echo $invoice_id; ?>,
|
||||
positions: positions
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
89
quote.php
89
quote.php
|
|
@ -326,27 +326,37 @@ if (isset($_GET['quote_id'])) {
|
|||
<tr data-item-id="<?php echo $item_id; ?>">
|
||||
<td class="d-print-none">
|
||||
<?php if ($quote_status !== "Invoiced" && $quote_status !== "Accepted" && $quote_status !== "Declined" && lookupUserPermission("module_sales") >= 2) { ?>
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#"
|
||||
data-toggle="ajax-modal"
|
||||
data-ajax-url="ajax/ajax_item_edit.php"
|
||||
data-ajax-id="<?php echo $item_id; ?>"
|
||||
>
|
||||
<i class="fa fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_quote_item=<?php echo $item_id; ?>">
|
||||
<i class="fa fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-sm btn-light drag-handle">
|
||||
<i class="fas fa-bars text-muted"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#"
|
||||
data-toggle="ajax-modal"
|
||||
data-ajax-url="ajax/ajax_item_edit.php"
|
||||
data-ajax-id="<?php echo $item_id; ?>"
|
||||
>
|
||||
<i class="fa fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_quote_item=<?php echo $item_id; ?>">
|
||||
<i class="fa fa-fw fa-trash mr-2"></i>Delete
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</td>
|
||||
<td class="grab-cursor"><?php echo $item_name; ?></td>
|
||||
<td><?php echo $item_name; ?></td>
|
||||
<td><?php echo nl2br($item_description); ?></td>
|
||||
<td class="text-center"><?php echo number_format($item_quantity, 2); ?></td>
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_price, $quote_currency_code); ?></td>
|
||||
|
|
@ -992,38 +1002,23 @@ require_once "includes/footer.php";
|
|||
}
|
||||
</script>
|
||||
|
||||
<script src="plugins/dragula/dragula.min.js"></script>
|
||||
<script src="plugins/SortableJS/Sortable.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var container = $('table#items tbody')[0];
|
||||
new Sortable(document.querySelector('table#items tbody'), {
|
||||
handle: '.drag-handle',
|
||||
animation: 150,
|
||||
onEnd: function (evt) {
|
||||
const rows = document.querySelectorAll('table#items tbody tr');
|
||||
const positions = Array.from(rows).map((row, index) => ({
|
||||
id: row.dataset.itemId,
|
||||
order: index
|
||||
}));
|
||||
|
||||
dragula([container])
|
||||
.on('drop', function (el, target, source, sibling) {
|
||||
// Handle the drop event to update the order in the database
|
||||
var rows = $(container).children();
|
||||
var positions = rows.map(function(index, row) {
|
||||
return {
|
||||
id: $(row).data('itemId'),
|
||||
order: index
|
||||
};
|
||||
}).get();
|
||||
|
||||
// Send the new order to the server
|
||||
$.ajax({
|
||||
url: 'ajax.php',
|
||||
method: 'POST',
|
||||
data: {
|
||||
update_quote_items_order: true,
|
||||
quote_id: <?php echo $quote_id; ?>,
|
||||
positions: positions
|
||||
},
|
||||
success: function(data) {
|
||||
// Handle success
|
||||
},
|
||||
error: function(error) {
|
||||
console.error('Error updating order:', error);
|
||||
}
|
||||
});
|
||||
$.post('ajax.php', {
|
||||
update_quote_items_order: true,
|
||||
quote_id: <?php echo $quote_id; ?>,
|
||||
positions: positions
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -272,26 +272,34 @@ if (isset($_GET['recurring_invoice_id'])) {
|
|||
|
||||
<tr data-item-id="<?php echo $item_id; ?>">
|
||||
<td class="d-print-none">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#"
|
||||
data-toggle="ajax-modal"
|
||||
data-ajax-url="ajax/ajax_item_edit.php"
|
||||
data-ajax-id="<?php echo $item_id; ?>"
|
||||
>
|
||||
<i class="fa fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_recurring_invoice_item=<?php echo $item_id; ?>"><i class="fa fa-fw fa-trash mr-2"></i>Delete</a>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-sm btn-light drag-handle">
|
||||
<i class="fas fa-bars text-muted"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-sm btn-light" type="button" data-toggle="dropdown">
|
||||
<i class="fas fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#"
|
||||
data-toggle="ajax-modal"
|
||||
data-ajax-url="ajax/ajax_item_edit.php"
|
||||
data-ajax-id="<?php echo $item_id; ?>"
|
||||
>
|
||||
<i class="fa fa-fw fa-edit mr-2"></i>Edit
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item text-danger confirm-link" href="post.php?delete_recurring_invoice_item=<?php echo $item_id; ?>"><i class="fa fa-fw fa-trash mr-2"></i>Delete</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="grab-cursor"><?php echo $item_name; ?></td>
|
||||
<td><?php echo $item_name; ?></td>
|
||||
<td><?php echo nl2br($item_description); ?></td>
|
||||
<td class="text-center"><?php echo $item_quantity; ?></td>
|
||||
<td class="text-right"><?php echo numfmt_format_currency($currency_format, $item_price, $recurring_invoice_currency_code); ?></td>
|
||||
|
|
@ -483,39 +491,23 @@ require_once "includes/footer.php";
|
|||
});
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet" href="plugins/dragula/dragula.min.css">
|
||||
<script src="plugins/dragula/dragula.min.js"></script>
|
||||
<script src="plugins/SortableJS/Sortable.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var container = $('table#items tbody')[0];
|
||||
new Sortable(document.querySelector('table#items tbody'), {
|
||||
handle: '.drag-handle',
|
||||
animation: 150,
|
||||
onEnd: function (evt) {
|
||||
const rows = document.querySelectorAll('table#items tbody tr');
|
||||
const positions = Array.from(rows).map((row, index) => ({
|
||||
id: row.dataset.itemId,
|
||||
order: index
|
||||
}));
|
||||
|
||||
dragula([container])
|
||||
.on('drop', function (el, target, source, sibling) {
|
||||
// Handle the drop event to update the order in the database
|
||||
var rows = $(container).children();
|
||||
var positions = rows.map(function(index, row) {
|
||||
return {
|
||||
id: $(row).data('itemId'),
|
||||
order: index
|
||||
};
|
||||
}).get();
|
||||
|
||||
// Send the new order to the server
|
||||
$.ajax({
|
||||
url: 'ajax.php',
|
||||
method: 'POST',
|
||||
data: {
|
||||
update_recurring_invoice_items_order: true,
|
||||
recurring_invoice_id: <?php echo $recurring_invoice_id; ?>,
|
||||
positions: positions
|
||||
},
|
||||
success: function(data) {
|
||||
// Handle success
|
||||
},
|
||||
error: function(error) {
|
||||
console.error('Error updating order:', error);
|
||||
}
|
||||
});
|
||||
$.post('ajax.php', {
|
||||
update_recurring_invoice_items_order: true,
|
||||
recurring_invoice_id: <?php echo $recurring_invoice_id; ?>,
|
||||
positions: positions
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue