2 Commits 4ea4f0a3a9 ... cb89d9fd37

Autor SHA1 Mensagem Data
  ttreasure cb89d9fd37 Made the buttons and columndefs datatables JSON dynamically driven from the DB. há 10 meses atrás
  ttreasure 3c3392f6f4 Added basic single-button action columns há 10 meses atrás

+ 4 - 0
app/Livewire/ShowReports.php

@@ -12,6 +12,8 @@ class ShowReports extends Component
     public $datatableName;
     public $datatableColumnsConfig;
     public $datatableHeadersConfig;
+    public $datatableButtonsConfig;
+    public $datatableColumnDefsConfig;
 
 
     public function mount($datatableName)
@@ -29,6 +31,8 @@ class ShowReports extends Component
         // Store the decoded JSON as a plain array
         $this->datatableColumnsConfig = json_decode($datatableConfigQuery->columns_config, true);
         $this->datatableHeadersConfig = json_decode($datatableConfigQuery->column_headers, true);
+        $this->datatableColumnDefsConfig = json_decode($datatableConfigQuery->column_defs, true);
+        $this->datatableButtonsConfig = json_decode($datatableConfigQuery->buttons, true);
     }
 
     public function render()

+ 49 - 0
database/migrations/2025_07_24_165629_add_buttons_and_columndefs_columns_to_datatables_table.php

@@ -0,0 +1,49 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('datatables', function (Blueprint $table) {
+            // Drop 5 old columns
+            $table->dropColumn(['enable_copy', 'enable_csv', 'enable_excel', 'enable_pdf', 'enable_print']);
+
+            // Add new JSON columns for buttons config
+            $buttons = [
+                ['extend' => 'copyHtml5',  'className' => 'dt-button'],
+                ['extend' => 'csvHtml5',   'className' => 'dt-button'],
+                ['extend' => 'excelHtml5', 'className' => 'dt-button'],
+                ['extend' => 'pdfHtml5',   'className' => 'dt-button'],
+                ['extend' => 'print',      'className' => 'dt-button'],
+            ];
+            $table->json('buttons')->default(json_encode($buttons));
+
+            $columnDefs = [
+            ['responsivePriority' => 1, 'targets' => 1],
+            ['responsivePriority' => 2, 'targets' => -1],
+            ['visible' => false, 'targets' => 0]
+        ];
+
+            $table->json('column_defs')->default(json_encode($columnDefs));
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+
+            Schema::table('datatables', function (Blueprint $table) {
+                // Drop the new JSON columns
+                $table->dropColumn(['buttons', 'column_defs']);
+            });
+    }
+};

+ 16 - 0
resources/css/datatables.css

@@ -37,3 +37,19 @@ body {
     background-color: white; /* even rows */
 }
 
+.action-button {
+    display: inline-block;
+    padding: 6px 12px;
+    background-color: grey;
+    color: black;
+    border: none;
+    border-radius: 4px;
+    text-decoration: none;
+    font-size: 14px;
+    cursor: pointer;
+}
+
+.action-button:hover {
+    background-color: darkgrey;
+}
+

+ 57 - 15
resources/js/datatables.js

@@ -14,20 +14,71 @@ import 'datatables.net-responsive-dt';
 
 
 
+
 // Ensure jQuery is available globally
 window.$ = window.jQuery = $;
 window.JSZip = JSZip;
 // Initialize DataTable
-let dataTableInstance;
+var dataTableInstance;
 var searchTerms ={};
 function initializeDataTable() {
     var dataTableName = document.getElementById('datatable-config').dataset.datatableName;
     var dataTableColumnsConfig = JSON.parse(document.getElementById('datatable-config').dataset.datatableColumnsConfig);
     var dataTableHeadersConfig = JSON.parse(document.getElementById('datatable-config').dataset.datatableHeadersConfig);
-    if ($.fn.DataTable.isDataTable(`#${dataTableName}-table`)) {
-        dataTableInstance.destroy();
-        $(`#${dataTableName}-table tbody`).empty(); // Clear rows to prevent residue
+    var dataTablesButtonsConfig = JSON.parse(document.getElementById('datatable-config').dataset.datatableButtonsConfig);
+    var dataTablesColumnDefsConfig = JSON.parse(document.getElementById('datatable-config').dataset.datatableColumnDefsConfig);
+
+
+    //Set up any action columns
+    function doActionButton(url, id)
+    {
+        window.open(url, "_blank");
     }
+    window.doActionButton=doActionButton;
+
+    var renderFunctions = [];
+    dataTableHeadersConfig.forEach(function (headerColumn, columnIndex){
+        if(headerColumn.type === "action")
+        {
+            let buttonUrl = dataTableColumnsConfig[columnIndex].buttonUrl;
+            let parameters = dataTableColumnsConfig[columnIndex].querystring_parameters;
+            console.log(parameters);
+            let renderBody = `if (type === "display") {console.log(row);`;
+            renderBody += `return '<button class="action-button" onclick="doActionButton(`;
+            renderBody += `\\'`+buttonUrl;
+            parameters.forEach(function (parameter, index){
+                if(index === 0)
+                {
+                    renderBody += '?';
+                }
+                else
+                {
+                    renderBody += '&';
+                }
+                for(let key in parameter)
+                {
+                    renderBody += key+'=';
+                    if(parameter[key] === 'row.id')
+                    {
+                        renderBody += '\'+'+encodeURIComponent(parameter[key])+'+\'';
+                    }
+                    else
+                    {
+                        renderBody += encodeURIComponent(parameter[key]);
+                    }
+                }
+
+            })
+            renderBody += `\\'`;
+            renderBody += ")\">"+dataTableColumnsConfig[columnIndex].buttonText+"</button>'}return data;";
+            renderFunctions[columnIndex] = new Function('data', 'type', 'row', 'meta', renderBody);
+            console.log(renderFunctions[columnIndex]);
+            dataTableColumnsConfig[columnIndex].searchable = false;
+            dataTableColumnsConfig[columnIndex].orderable = false;
+            dataTableColumnsConfig[columnIndex].render = renderFunctions[columnIndex];
+
+        }
+    })
 
     dataTableInstance = $(`#${dataTableName}-table`).DataTable({
         responsive: true,
@@ -81,20 +132,11 @@ function initializeDataTable() {
         },
         columns: dataTableColumnsConfig,
         dom: 'lBfrtip',
-        buttons: [
-            { extend: 'copyHtml5', className: 'dt-button' },
-            { extend: 'csvHtml5', className: 'dt-button' },
-            { extend: 'excelHtml5', className: 'dt-button' },
-            { extend: 'pdfHtml5', className: 'dt-button' },
-            { extend: 'print', className: 'dt-button' },
-        ],
+        buttons: dataTablesButtonsConfig,
         layout: {
             topStart: 'buttons'
         },
-        columnDefs: [
-            { responsivePriority: 1, targets: 0 },
-            { responsivePriority: 2, targets: -1 }
-        ]
+        columnDefs: dataTablesColumnDefsConfig
     });
 }
 document.addEventListener('livewire:init', function () {

+ 3 - 1
resources/views/livewire/show-reports.blade.php

@@ -3,7 +3,9 @@
     <div id="datatable-config"
          data-datatable-name="{{ $datatableName }}"
          data-datatable-columns-config='@json($datatableColumnsConfig)'
-         data-datatable-headers-config='@json($datatableHeadersConfig)'>
+         data-datatable-headers-config='@json($datatableHeadersConfig)'
+         data-datatable-buttons-config='@json($datatableButtonsConfig)'
+         data-datatable-column-defs-config='@json($datatableColumnDefsConfig)'>
     </div>
 
     <table id="{{$datatableName}}-table" class="bg-white border border-gray-300">