- Changes to the list views - now using tabulator with filtering and sorting, client-side pagination, ...

- Adaptation of all list views in the app
This commit is contained in:
Josako
2025-07-14 18:58:54 +02:00
parent acad28b623
commit 000636a229
50 changed files with 2162 additions and 2174 deletions

View File

@@ -0,0 +1,183 @@
/**
* EveAI List View Component
* JavaScript functionaliteit voor het beheren van lijst-weergaven
*/
// Namespace aanmaken als deze nog niet bestaat
if (typeof window.EveAI === 'undefined') {
window.EveAI = {};
}
// List View namespace
window.EveAI.ListView = {
// Opslag voor lijst-view instanties
instances: {},
/**
* Initialiseer een Tabulator lijst-view
* @param {string} elementId - ID van het HTML element
* @param {object} config - Configuratie object voor Tabulator
* @returns {Tabulator} - Tabulator instantie
*/
initialize: function(elementId, config) {
// Combineer standaard configuratie met aangepaste configuratie
const defaultConfig = {
height: 600,
layout: "fitColumns",
selectable: true,
movableColumns: true,
pagination: "local",
paginationSize: 15,
paginationSizeSelector: [10, 15, 20, 50, 100],
};
const tableConfig = {...defaultConfig, ...config};
// Voeg rij selectie event toe
tableConfig.rowSelectionChanged = (data, rows) => {
console.log("Rij selectie gewijzigd:", rows.length, "rijen geselecteerd");
// Update de geselecteerde rij in onze instance
if (this.instances[elementId]) {
this.instances[elementId].selectedRow = rows.length > 0 ? rows[0].getData() : null;
this.updateActionButtons(elementId);
}
};
// Initialiseer de Tabulator
try {
const table = new Tabulator(`#${elementId}`, tableConfig);
// Bewaar de instance
this.instances[elementId] = {
table: table,
config: config || {},
selectedRow: null
};
// Bij initialisatie, update de knoppen (standaard inactief voor requiresSelection=true)
setTimeout(() => {
this.updateActionButtons(elementId);
}, 0);
return table;
} catch (error) {
console.error(`Fout bij het initialiseren van Tabulator voor ${elementId}:`, error);
return null;
}
},
/**
* Afhandelen van actieknoppen
* @param {string} action - Actie identifier
* @param {boolean} requiresSelection - Of de actie een selectie vereist
* @param {string} tableId - ID van de tabel
* @returns {boolean} - Succes indicator
*/
/**
* Update actieknoppen op basis van geselecteerde rij
* @param {string} tableId - ID van de tabel
*/
updateActionButtons: function(tableId) {
const instance = this.instances[tableId];
if (!instance) return;
const container = document.getElementById(tableId);
if (!container) return;
const buttons = container.parentElement.querySelectorAll('button[onclick*="handleListViewAction"]');
buttons.forEach(button => {
// Parse de onclick attribuut om de actiewaarde te krijgen
const onclickAttr = button.getAttribute('onclick');
const match = onclickAttr.match(/handleListViewAction\('([^']+)'/);
if (match) {
const actionValue = match[1];
// Vind de actie in de configuratie
const action = instance.config.actions.find(a => a.value === actionValue);
if (action && action.requiresSelection === true) {
// Schakel de knop in/uit op basis van selectie
button.disabled = !instance.selectedRow;
}
}
});
// Update de verborgen input met geselecteerde rij data
this._updateSelectedRowInput(tableId);
},
/**
* Update de verborgen input met geselecteerde rij gegevens
* @param {string} tableId - ID van de tabel
* @private
*/
_updateSelectedRowInput: function(tableId) {
const instance = this.instances[tableId];
const hiddenInput = document.getElementById(`${tableId}-selected-row`);
if (hiddenInput && instance && instance.selectedRow) {
// Bewaar de geselecteerde rij-ID
hiddenInput.value = JSON.stringify({value: instance.selectedRow.id});
} else if (hiddenInput) {
hiddenInput.value = '';
}
},
handleAction: function(action, requiresSelection, tableId) {
const selectedRowInput = document.getElementById(`${tableId}-selected-row`);
const actionInput = document.getElementById(`${tableId}-action`);
const table = Tabulator.findTable(`#${tableId}`)[0];
if (!table) {
console.error(`Tabulator tabel met ID ${tableId} niet gevonden`);
return false;
}
// Als de actie een selectie vereist, controleer of er een rij is geselecteerd
if (requiresSelection) {
const selectedRows = table.getSelectedRows();
if (selectedRows.length === 0) {
alert('Selecteer a.u.b. eerst een item uit de lijst.');
return false;
}
// Haal de data van de geselecteerde rij op en sla deze op
const rowData = selectedRows[0].getData();
selectedRowInput.value = JSON.stringify({ value: rowData.id });
// Update de instance als deze bestaat
if (this.instances[tableId]) {
this.instances[tableId].selectedRow = rowData;
}
}
// Stel de actie in en verstuur het formulier
actionInput.value = action;
// Zoek het juiste formulier en verstuur het
const form = document.getElementById(`${tableId}-form`) ||
table.element.closest('form');
if (form) {
form.submit();
return true;
} else {
console.error(`Geen formulier gevonden voor tabel ${tableId}`);
return false;
}
}
};
// Functie om beschikbaar te maken in templates
function handleListViewAction(action, requiresSelection) {
// Vind het tableId op basis van de button die is aangeklikt
const target = event?.target || event?.srcElement;
// Vind het formulier en tableId op basis daarvan
const form = target ? target.closest('form') : null;
const tableId = form ? form.id.replace('-form', '') : 'unknown_table';
return window.EveAI.ListView.handleAction(action, requiresSelection, tableId);
}
console.log('EveAI List View component geladen');

View File

@@ -0,0 +1,83 @@
/**
* EveAI Tabulator Setup
* Standaard Tabulator configuratie voor consistente tabelweergaven
*/
document.addEventListener('DOMContentLoaded', function() {
// Controleer of Tabulator is geladen
if (typeof Tabulator !== 'function') {
console.warn('Tabulator is niet geladen - overslaan van initialisatie');
return;
}
// Zorg ervoor dat de modules correct zijn gedefinieerd
if (!Tabulator.modules) {
Tabulator.modules = {};
}
if (!Tabulator.modules.format) {
Tabulator.modules.format = { formatters: {} };
} else if (!Tabulator.modules.format.formatters) {
Tabulator.modules.format.formatters = {};
}
// Registreer algemene Tabulator opties en formatters
// Gebruik rechtstreekse toewijzing i.p.v. extendModule indien deze functie niet beschikbaar is
if (typeof Tabulator.extendModule === 'function') {
try {
Tabulator.extendModule("format", "formatters", {
// Aangepaste formatter voor boolean waarden met mooie iconen
"boolean": function(cell, formatterParams){
const value = cell.getValue();
if (value === true || value === 'true' || value === 1 || value === '1') {
return '<i class="fas fa-check text-success"></i>';
} else if (value === false || value === 'false' || value === 0 || value === '0') {
return '<i class="fas fa-times text-danger"></i>';
}
return ''; // Geef lege string terug voor null/undefined waarden
}
});
} catch (e) {
console.warn('Fout bij extendModule:', e);
// Fallback: rechtstreeks formatters toevoegen
Tabulator.modules.format.formatters.boolean = function(cell, formatterParams){
const value = cell.getValue();
if (value === true || value === 'true' || value === 1 || value === '1') {
return '<i class="fas fa-check text-success"></i>';
} else if (value === false || value === 'false' || value === 0 || value === '0') {
return '<i class="fas fa-times text-danger"></i>';
}
return '';
};
}
} else {
// Directe toewijzing als extendModule niet beschikbaar is
Tabulator.modules.format.formatters.boolean = function(cell, formatterParams){
const value = cell.getValue();
if (value === true || value === 'true' || value === 1 || value === '1') {
return '<i class="fas fa-check text-success"></i>';
} else if (value === false || value === 'false' || value === 0 || value === '0') {
return '<i class="fas fa-times text-danger"></i>';
}
return '';
};
}
// Definieer standaard tabelconfiguratie
Tabulator.defaultOptions = {
...Tabulator.defaultOptions,
layout: "fitColumns",
responsiveLayout: false,
pagination: "local",
paginationSize: 25,
paginationSizeSelector: [10, 25, 50, 100],
movableColumns: true,
tooltips: false,
placeholder: "No Data Available",
// Verbeterde virtuele DOM-instellingen voor betere prestaties
renderVerticalBuffer: 20,
virtualDomBuffer: 80
};
console.log('EveAI Tabulator Setup successfully loaded');
});