feat: Implement invoice creation functionality and integrate DataTables for invoice listing with dynamic column rendering.
This commit is contained in:
@@ -2,32 +2,34 @@
|
||||
|
||||
@php
|
||||
$dtColumns = collect($columns)
|
||||
->map(function ($c) {
|
||||
->map(function ($c, $index) {
|
||||
return [
|
||||
'data' => $c['key'],
|
||||
'name' => $c['key'],
|
||||
'orderable' => $c['orderable'] ?? true,
|
||||
'searchable' => $c['searchable'] ?? true,
|
||||
'className' => $c['className'] ?? '',
|
||||
'visible' => $c['visible'] ?? true,
|
||||
];
|
||||
})
|
||||
->values();
|
||||
@endphp
|
||||
|
||||
@if ($bulkDeleteUrl)
|
||||
<div class="d-flex justify-content-start align-items-center mb-3" id="{{ $id }}-bulk-actions"
|
||||
style="display: none !important;">
|
||||
<div class="bg-danger-subtle text-danger rounded-3 d-flex align-items-center gap-3 px-4 py-2">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<i data-lucide="alert-circle" width="16" height="16"></i>
|
||||
<span class="fw-medium"><span id="{{ $id }}-selected-count">0</span> items selected</span>
|
||||
</div>
|
||||
<div class="vr bg-danger opacity-25"></div>
|
||||
<x-button-c-r-m type="button" variant="danger" size="sm" icon="trash-2" id="{{ $id }}-bulk-delete-opener-btn"
|
||||
class="shadow-sm">
|
||||
Delete Selected
|
||||
</x-button-c-r-m>
|
||||
<div class="d-flex justify-content-start align-items-center mb-3" id="{{ $id }}-bulk-actions"
|
||||
style="display: none !important;">
|
||||
<div class="bg-danger-subtle text-danger rounded-3 d-flex align-items-center gap-3 px-4 py-2">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<i data-lucide="alert-circle" width="16" height="16"></i>
|
||||
<span class="fw-medium"><span id="{{ $id }}-selected-count">0</span> items selected</span>
|
||||
</div>
|
||||
<div class="vr bg-danger opacity-25"></div>
|
||||
<x-button-c-r-m type="button" variant="danger" size="sm" icon="trash-2" id="{{ $id }}-bulk-delete-opener-btn"
|
||||
class="shadow-sm">
|
||||
Delete Selected
|
||||
</x-button-c-r-m>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="{{ $id }}-bulk-delete-modal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
@@ -56,6 +58,7 @@ $dtColumns = collect($columns)
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="data-table-wrapper position-relative shadow-none">
|
||||
<div class="loading-process" id="{{ $id }}-loading" style="display: none;">
|
||||
<div class="loading-bar"></div>
|
||||
@@ -110,6 +113,27 @@ $dtColumns = collect($columns)
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="{{ $id }}-column-offcanvas">
|
||||
<div class="offcanvas-header border-bottom">
|
||||
<h5 class="offcanvas-title">Column Visibility</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
@foreach($columns as $index => $col)
|
||||
@if((!isset($col['visibility']) || $col['visibility'] !== false) && $col['key'] !== 'checkbox')
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input type="checkbox" class="form-check-input column-toggle"
|
||||
data-column-index="{{ $index }}"
|
||||
id="{{ $id }}-col-{{ $index }}"
|
||||
{{ !isset($col['visible']) || $col['visible'] !== false ? 'checked' : '' }}>
|
||||
<label class="form-check-label" for="{{ $id }}-col-{{ $index }}">{{ $col['label'] }}</label>
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@push('custom-scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
@@ -139,7 +163,7 @@ $dtColumns = collect($columns)
|
||||
zeroRecords: '<div class="d-flex flex-column align-items-center justify-content-center py-5"><div class="text-secondary mb-3"><i data-lucide="inbox" width="28" height="28" stroke-width="1.5"></i></div><h6 class="text-secondary fw-medium">No matching records found</h6></div>',
|
||||
emptyTable: '<div class="d-flex flex-column align-items-center justify-content-center py-5"><div class="text-secondary mb-3"><i data-lucide="inbox" width="28" height="28" stroke-width="1.5"></i></div><h6 class="text-secondary fw-medium">No data available</h6></div>'
|
||||
},
|
||||
dom: "<'row px-3 py-2 align-items-center'<'col-sm-12 col-md-6 d-inline-flex align-items-center gap-2'<'dt-filter-toggle'>f><'col-sm-12 col-md-6 d-inline-flex align-items-center justify-content-end gap-2'l>>" +
|
||||
dom: "<'row px-3 py-2 align-items-center'<'col-sm-12 col-md-6 d-inline-flex align-items-center gap-2'<'dt-filter-toggle'><'dt-column-toggle'>f><'col-sm-12 col-md-6 d-inline-flex align-items-center justify-content-end gap-2'l>>" +
|
||||
"<'row p-0'<'col-sm-12'tr>>" +
|
||||
"<'row px-3 pb-3 pt-3 align-items-center'<'col-sm-12 col-md-5 text-muted small d-inline-flex align-items-center'i><'col-sm-12 col-md-7 d-inline-flex align-items-center justify-content-end gap-2'p>>",
|
||||
initComplete: function () {
|
||||
@@ -152,6 +176,13 @@ $dtColumns = collect($columns)
|
||||
'</button>'
|
||||
);
|
||||
|
||||
wrapper.find('.dt-column-toggle').html(
|
||||
'<button type="button" class="btn btn-sm btn-outline-secondary d-flex align-items-center gap-1" data-bs-toggle="offcanvas" data-bs-target="#{{ $id }}-column-offcanvas">' +
|
||||
'<i data-lucide="columns" width="14" height="14"></i>' +
|
||||
'<span>Columns</span>' +
|
||||
'</button>'
|
||||
);
|
||||
|
||||
$('#{{ $id }}-filter-toggle-btn').on('click', function () {
|
||||
var filterRow = $('#{{ $id }}-filter-row');
|
||||
var btn = $(this);
|
||||
@@ -207,6 +238,12 @@ $dtColumns = collect($columns)
|
||||
}
|
||||
});
|
||||
|
||||
$('#{{ $id }}-column-offcanvas').on('change', '.column-toggle', function () {
|
||||
var columnIdx = $(this).data('column-index');
|
||||
var column = table.column(columnIdx);
|
||||
column.visible($(this).is(':checked'));
|
||||
});
|
||||
|
||||
$('#{{ $id }} tbody').on('dblclick', 'tr', function () {
|
||||
const editLink = $(this).find('a.btn-outline-primary, a[href*="edit"]').first();
|
||||
if (editLink.length && editLink.attr('href')) {
|
||||
|
||||
Reference in New Issue
Block a user