- 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:
@@ -1,97 +0,0 @@
|
||||
|
||||
{% extends 'base.html' %}
|
||||
{% from 'macros.html' import render_selectable_table, render_pagination, render_filter_field, render_date_filter_field, render_collapsible_section, render_selectable_sortable_table_with_dict_headers %}
|
||||
|
||||
{% block title %}Assets{% endblock %}
|
||||
|
||||
{% block content_title %}Assets{% endblock %}
|
||||
{% block content_description %}View Assets{% endblock %}
|
||||
{% block content_class %}<div class="col-xl-12 col-lg-5 col-md-7 mx-auto"></div>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Filter Form -->
|
||||
{% set filter_form %}
|
||||
<form method="GET" action="{{ url_for('interaction_bp.assets') }}">
|
||||
{{ render_filter_field('type', 'Type', filter_options['type'], filters.get('type', [])) }}
|
||||
{{ render_filter_field('file_type', 'Bestandstype', filter_options['file_type'], filters.get('file_type', [])) }}
|
||||
|
||||
<button type="submit" class="btn btn-primary">Apply Filters</button>
|
||||
</form>
|
||||
{% endset %}
|
||||
|
||||
{{ render_collapsible_section('Filter', 'Filter Options', filter_form) }}
|
||||
|
||||
<div class="form-group mt-3">
|
||||
<form method="POST" action="{{ url_for('interaction_bp.handle_asset_selection') }}" id="assetsForm">
|
||||
<!-- Assets Table -->
|
||||
{{ render_selectable_sortable_table_with_dict_headers(
|
||||
headers=[
|
||||
{"text": "ID", "sort": "id"},
|
||||
{"text": "Naam", "sort": "name"},
|
||||
{"text": "Type", "sort": "type"},
|
||||
{"text": "Type Versie", "sort": "type_version"},
|
||||
{"text": "Bestandstype", "sort": "file_type"},
|
||||
{"text": "Laatst Gebruikt", "sort": "last_used_at"}
|
||||
],
|
||||
rows=rows,
|
||||
selectable=True,
|
||||
id="assetsTable",
|
||||
sort_by=sort_by,
|
||||
sort_order=sort_order
|
||||
) }}
|
||||
<div class="form-group mt-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<button type="submit" name="action" value="edit_asset" class="btn btn-primary" onclick="return validateTableSelection('assetsForm')">Edit Asset</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content_footer %}
|
||||
{{ render_pagination(pagination, 'interaction_bp.assets') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const table = document.getElementById('assetsTable');
|
||||
const headers = table.querySelectorAll('th.sortable');
|
||||
|
||||
headers.forEach(header => {
|
||||
header.addEventListener('click', function() {
|
||||
const sortBy = this.dataset.sort;
|
||||
let sortOrder = 'asc';
|
||||
|
||||
if (this.querySelector('.fa-sort-up')) {
|
||||
sortOrder = 'desc';
|
||||
} else if (this.querySelector('.fa-sort-down')) {
|
||||
sortOrder = 'none';
|
||||
}
|
||||
|
||||
window.location.href = updateQueryStringParameter(window.location.href, 'sort_by', sortBy);
|
||||
window.location.href = updateQueryStringParameter(window.location.href, 'sort_order', sortOrder);
|
||||
});
|
||||
});
|
||||
|
||||
function updateQueryStringParameter(uri, key, value) {
|
||||
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
|
||||
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
|
||||
if (uri.match(re)) {
|
||||
return uri.replace(re, '$1' + key + "=" + value + '$2');
|
||||
}
|
||||
else {
|
||||
return uri + separator + key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
table.addEventListener('change', function(event) {
|
||||
if (event.target.type === 'radio') {
|
||||
var selectedRow = event.target.closest('tr');
|
||||
var assetId = selectedRow.cells[1].textContent;
|
||||
console.log('Selected Asset ID:', assetId);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -1,26 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% from 'macros.html' import render_selectable_table, render_pagination %}
|
||||
|
||||
{% block title %}Chat Sessions{% endblock %}
|
||||
|
||||
{% block content_title %}Chat Sessions{% endblock %}
|
||||
{% block content_description %}View Chat Sessions for Tenant{% endblock %}
|
||||
{% block content_class %}<div class="col-xl-12 col-lg-5 col-md-7 mx-auto"></div>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<form method="POST" action="{{ url_for('interaction_bp.handle_chat_session_selection') }}" id="chatSessionsForm">
|
||||
{{ render_selectable_table(headers=["ID", "Session ID", "Session Start", "Session End"], rows=rows, selectable=True, id="chatSessionsTable") }}
|
||||
<div class="form-group mt-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<button type="submit" name="action" value="view_chat_session" class="btn btn-primary" onclick="return validateTableSelection('chatSessionsForm')">View Chat Session</button>
|
||||
<button type="submit" name="action" value="chat_session_interactions" class="btn btn-primary" onclick="return validateTableSelection('chatSessionsForm')">View Chat Session interactions</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content_footer %}
|
||||
{{ render_pagination(pagination, 'interaction_bp.chat_sessions') }}
|
||||
{% endblock %}
|
||||
@@ -1,26 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
{% from 'macros.html' import render_selectable_table, render_pagination %}
|
||||
|
||||
{% block title %}Specialist Magic Links{% endblock %}
|
||||
|
||||
{% block content_title %}Specialist Magic Links{% endblock %}
|
||||
{% block content_description %}View Specialists Magic Links{% endblock %}
|
||||
{% block content_class %}<div class="col-xl-12 col-lg-5 col-md-7 mx-auto"></div>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<form method="POST" action="{{ url_for('interaction_bp.handle_specialist_magic_link_selection') }}" id="specialistMagicLinksForm">
|
||||
{{ render_selectable_table(headers=["Specialist ML ID", "Name", "Magic Link Code"], rows=rows, selectable=True, id="specialistMagicLinksTable") }}
|
||||
<div class="form-group mt-3 d-flex justify-content-between">
|
||||
<div>
|
||||
<button type="submit" name="action" value="edit_specialist_magic_link" class="btn btn-primary" onclick="return validateTableSelection('specialistMagicLinksForm')">Edit Specialist Magic Link</button>
|
||||
</div>
|
||||
<button type="submit" name="action" value="create_specialist_magic_link" class="btn btn-success">Register Specialist Magic Link</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content_footer %}
|
||||
{{ render_pagination(pagination, 'interaction_bp.specialist_magic_links') }}
|
||||
{% endblock %}
|
||||
@@ -1,77 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Specialists{% endblock %}
|
||||
{% block content_title %}Specialists{% endblock %}
|
||||
{% block content_description %}View Specialists for Tenant{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<form method="POST" action="{{ url_for('interaction_bp.handle_specialist_selection') }}" id="specialistsForm" onsubmit="return validateSpecialistSelection()">
|
||||
<div id="specialists-list-view" class="tabulator-list-view"></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Include the list view component -->
|
||||
{% include 'eveai_list_view.html' %}
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Laad data met een kleine vertraging om de pagina eerst te laten renderen
|
||||
setTimeout(() => {
|
||||
// Initialize the list view met gepagineerde data en optimalisaties
|
||||
const tabulatorTable = EveAI.ListView.initialize('specialists-list-view', {
|
||||
data: {{ specialists_data | tojson }},
|
||||
columns: {{ columns | tojson }},
|
||||
initialSort: {{ initial_sort | tojson }},
|
||||
actions: {{ actions | tojson }},
|
||||
selectable: true,
|
||||
usePagination: true, // Gebruik paginatie in plaats van progressieve lading
|
||||
tableHeight: 800 // Hogere tabel voor specialists view
|
||||
});
|
||||
|
||||
// Extra debug event listeners
|
||||
if (tabulatorTable) {
|
||||
console.log('Tabulator tabel succesvol geïnitialiseerd');
|
||||
|
||||
// Voeg een klik-event toe aan de hele tabel container voor een betere gebruikerservaring
|
||||
document.querySelector('.tabulator-container').addEventListener('click', function(e) {
|
||||
console.log('Tabulator container click event');
|
||||
// De specifieke row click events worden afgehandeld door Tabulator zelf
|
||||
});
|
||||
} else {
|
||||
console.error('Tabulator tabel kon niet worden geïnitialiseerd');
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
|
||||
// Validation function for form submission
|
||||
function validateSpecialistSelection() {
|
||||
const selectedRow = document.getElementById('specialists-list-view-selected-row');
|
||||
const actionButton = document.activeElement;
|
||||
|
||||
// Als de actie geen selectie vereist, ga dan altijd door
|
||||
if (actionButton && actionButton.classList.contains('btn-success')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!selectedRow || !selectedRow.value) {
|
||||
alert('Selecteer a.u.b. eerst een specialist.');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const selection = JSON.parse(selectedRow.value);
|
||||
// Controleer of er een specialist is geselecteerd
|
||||
if (!selection.value) {
|
||||
alert('Selecteer a.u.b. eerst een specialist.');
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
alert('Er is een fout opgetreden bij het verwerken van de selectie.');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user