diff --git a/common/utils/cache/base.py b/common/utils/cache/base.py index 4e7cd01..46de589 100644 --- a/common/utils/cache/base.py +++ b/common/utils/cache/base.py @@ -121,7 +121,7 @@ class CacheHandler(Generic[T]): region_name = getattr(self.region, 'name', 'default_region') key = CacheKey({k: identifiers[k] for k in self._key_components}) - return f"{region_name}_{self.prefix}:{str(key)}" + return f"{region_name}:{self.prefix}:{str(key)}" def get(self, creator_func, **identifiers) -> T: """ @@ -179,7 +179,7 @@ class CacheHandler(Generic[T]): Deletes all keys that start with the region prefix. """ # Construct the pattern for all keys in this region - pattern = f"{self.region}_{self.prefix}:*" + pattern = f"{self.region}:{self.prefix}:*" # Assuming Redis backend with dogpile, use `delete_multi` or direct Redis access if hasattr(self.region.backend, 'client'): diff --git a/config/agents/globals/RAG_AGENT/1.2.0.yaml b/config/agents/globals/RAG_AGENT/1.2.0.yaml index 360c6e9..bb64f2d 100644 --- a/config/agents/globals/RAG_AGENT/1.2.0.yaml +++ b/config/agents/globals/RAG_AGENT/1.2.0.yaml @@ -21,7 +21,7 @@ allowed_models: - "mistral.mistral-small-latest" - "mistral.mistral-medium-latest" - "mistral.magistral-medium-latest" -temperature: 0.4 +temperature: 0.3 metadata: author: "Josako" date_added: "2025-01-08" diff --git a/config/static-manifest/manifest.json b/config/static-manifest/manifest.json index de931d8..70bb5e1 100644 --- a/config/static-manifest/manifest.json +++ b/config/static-manifest/manifest.json @@ -1,6 +1,6 @@ { "dist/chat-client.js": "dist/chat-client.8fea5d6b.js", "dist/chat-client.css": "dist/chat-client.22ac21c3.css", - "dist/main.js": "dist/main.c5b0c81d.js", + "dist/main.js": "dist/main.6a617099.js", "dist/main.css": "dist/main.06893f70.css" } \ No newline at end of file diff --git a/eveai_app/static/assets/js/eveai-list-view.js b/eveai_app/static/assets/js/eveai-list-view.js index 31cdc76..798a876 100644 --- a/eveai_app/static/assets/js/eveai-list-view.js +++ b/eveai_app/static/assets/js/eveai-list-view.js @@ -12,6 +12,21 @@ if (typeof window.EveAI === 'undefined') { window.EveAI.ListView = { // Opslag voor lijst-view instanties instances: {}, + // Registry voor custom formatters (kan uitgebreid worden door templates) + formatters: { + // typeBadge: toont een badge voor agent/task/tool (robuust met Bootstrap 5 classes) + typeBadge: function(cell) { + const raw = (cell.getValue() || '').toString(); + const val = raw.toLowerCase(); + const map = { + 'agent': { cls: 'badge text-bg-primary', label: 'Agent' }, + 'task': { cls: 'badge text-bg-warning', label: 'Task' }, + 'tool': { cls: 'badge text-bg-info', label: 'Tool' }, + }; + const conf = map[val] || { cls: 'badge text-bg-secondary', label: (raw ? raw : 'Item') }; + return `${conf.label}`; + } + }, /** * Initialiseer een Tabulator lijst-view @@ -24,19 +39,50 @@ window.EveAI.ListView = { const defaultConfig = { height: 600, layout: "fitColumns", - selectable: true, + selectable: 1, // single-row selection for consistent UX across Tabulator versions movableColumns: true, pagination: "local", paginationSize: 15, paginationSizeSelector: [10, 15, 20, 50, 100], }; + // Respecteer eventueel meegegeven tableHeight alias + if (config && typeof config.tableHeight !== 'undefined' && typeof config.height === 'undefined') { + config.height = config.tableHeight; + } + + // Los string-formatters op naar functies via registry + if (config && Array.isArray(config.columns)) { + config.columns = config.columns.map(col => { + const newCol = { ...col }; + if (typeof newCol.formatter === 'string' && window.EveAI && window.EveAI.ListView && window.EveAI.ListView.formatters) { + const key = newCol.formatter.trim(); + const fmt = window.EveAI.ListView.formatters[key]; + if (typeof fmt === 'function') { + newCol.formatter = fmt; + } + } + return newCol; + }); + } + const tableConfig = {...defaultConfig, ...config}; + // Enforce single-row selection across Tabulator versions + if (tableConfig.selectable === true) { + tableConfig.selectable = 1; + } + + // Respect and enforce unique row index across Tabulator versions + if (config && typeof config.index === 'string' && config.index) { + // Tabulator v4/v5 + tableConfig.index = config.index; + // Tabulator v6+ (alias) + tableConfig.indexField = config.index; + } + // 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; @@ -60,6 +106,26 @@ window.EveAI.ListView = { this.updateActionButtons(elementId); }, 0); + // Forceer enkelvoudige selectie op klik voor consistente UX + try { + table.on('rowClick', function(e, row) { + // voorkom multi-select: altijd eerst deselecteren + row.getTable().deselectRow(); + row.select(); + }); + table.on('cellClick', function(e, cell) { + const row = cell.getRow(); + row.getTable().deselectRow(); + row.select(); + }); + // Optioneel: cursor als pointer bij hover + table.on('rowFormatter', function(row) { + row.getElement().style.cursor = 'pointer'; + }); + } catch (e) { + console.warn('Kon click-selectie handlers niet registreren:', e); + } + return table; } catch (error) { console.error(`Fout bij het initialiseren van Tabulator voor ${elementId}:`, error); @@ -168,16 +234,94 @@ window.EveAI.ListView = { } }; -// 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; +// Functie om beschikbaar te maken in templates (met guard en expliciete event-parameter) +if (typeof window.handleListViewAction !== 'function') { + window.handleListViewAction = function(action, requiresSelection, e) { + const evt = e || undefined; // geen gebruik van deprecated window.event + const target = evt && (evt.target || evt.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'; + // 1) Bepaal tableId zo robuust mogelijk + let tableId = null; + if (target) { + // Zoek het werkelijke trigger element (button/anchor) i.p.v. een child node + const trigger = (typeof target.closest === 'function') ? target.closest('button, a') : target; - return window.EveAI.ListView.handleAction(action, requiresSelection, tableId); + // a) Respecteer expliciete data-attribute op knop + tableId = trigger && trigger.getAttribute ? trigger.getAttribute('data-table-id') : null; + + if (!tableId) { + // b) Zoek dichtstbijzijnde container met een tabulator-list-view erin + const containerEl = trigger && typeof trigger.closest === 'function' ? trigger.closest('.container') : null; + const scopedTable = containerEl ? containerEl.querySelector('.tabulator-list-view') : null; + tableId = scopedTable ? scopedTable.id : null; + } + if (!tableId) { + // c) Val terug op dichtstbijzijnde form id-afleiding (enkel als het een -form suffix heeft) + const form = trigger && typeof trigger.closest === 'function' ? trigger.closest('form') : null; + if (form && typeof form.id === 'string' && form.id.endsWith('-form')) { + tableId = form.id.slice(0, -'-form'.length); + } + } + } + if (!tableId) { + // d) Laatste redmiddel: pak de eerste tabulator-list-view op de pagina + const anyTable = document.querySelector('.tabulator-list-view'); + tableId = anyTable ? anyTable.id : null; + } + if (!tableId) { + console.error('Kan tableId niet bepalen voor action:', action); + return false; + } + + const listView = window.EveAI && window.EveAI.ListView ? window.EveAI.ListView : null; + const instance = listView && listView.instances ? listView.instances[tableId] : null; + + // 2) Indien selectie vereist, enforce + if (requiresSelection === true) { + if (!instance || !instance.selectedRow) { + // Probeer nog de Tabulator API als instance ontbreekt + try { + const table = Tabulator.findTable(`#${tableId}`)[0]; + const rows = table ? table.getSelectedRows() : []; + if (!rows || rows.length === 0) { + alert('Selecteer eerst een item uit de lijst.'); + return false; + } + if (instance) instance.selectedRow = rows[0].getData(); + } catch (_) { + alert('Selecteer eerst een item uit de lijst.'); + return false; + } + } + } + + // 3) Embedded handler krijgt voorrang + const embeddedHandlers = listView && listView.embeddedHandlers ? listView.embeddedHandlers : null; + const embedded = embeddedHandlers && embeddedHandlers[tableId]; + if (typeof embedded === 'function') { + try { + embedded(action, instance ? instance.selectedRow : null, tableId); + return true; + } catch (err) { + console.error('Embedded handler error:', err); + return false; + } + } + + // 4) Vervallen naar legacy form submit/JS handler + if (listView && typeof listView.handleAction === 'function') { + return listView.handleAction(action, requiresSelection, tableId); + } + + // 5) Allerbeste laatste fallback – probeer form submit met hidden inputs + const actionInput = document.getElementById(`${tableId}-action`); + if (actionInput) actionInput.value = action; + const form = document.getElementById(`${tableId}-form`); + if (form) { form.submit(); return true; } + + console.error('Geen geldige handler gevonden voor action:', action); + return false; + } } console.log('EveAI List View component geladen'); diff --git a/eveai_app/templates/eveai_list_view.html b/eveai_app/templates/eveai_list_view.html index c9723fb..140b455 100644 --- a/eveai_app/templates/eveai_list_view.html +++ b/eveai_app/templates/eveai_list_view.html @@ -16,7 +16,7 @@
{% for action in actions if action.position != 'right' %} + {% endif %} + + +
+ + {% if enable_reset_defaults %} + {% endif %} -
- - -
{% endblock %} {% block content_footer %} diff --git a/eveai_app/templates/interaction/edit_specialist.html b/eveai_app/templates/interaction/edit_specialist.html index 3ea1708..4e23a57 100644 --- a/eveai_app/templates/interaction/edit_specialist.html +++ b/eveai_app/templates/interaction/edit_specialist.html @@ -32,23 +32,8 @@ - - - @@ -63,17 +48,17 @@ {% endfor %} -
-
-
-
-
- Specialist Overview -
-
-
-
-
+{#
#} +{#
#} +{#
#} +{#
#} +{#
#} +{# Specialist Overview#} +{#
#} +{#
#} +{#
#} +{#
#} +{#
#} @@ -88,79 +73,28 @@ {% endfor %} - -
+ +
- {{ render_selectable_table( - headers=["Agent ID", "Name", "Type", "Type Version"], - rows=agent_rows if agent_rows else [], - selectable=True, - id="agentsTable", - is_component_selector=True - ) }} -
- +
+ + +
+
+
+ +
+
- - -
-
-
- {{ render_selectable_table( - headers=["Task ID", "Name", "Type", "Type Version"], - rows=task_rows if task_rows else [], - selectable=True, - id="tasksTable", - is_component_selector=True - ) }} -
- -
-
-
-
- - -
-
-
- {{ render_selectable_table( - headers=["Tool ID", "Name", "Type", "Type Version"], - rows=tool_rows if tool_rows else [], - selectable=True, - id="toolsTable", - is_component_selector=True - ) }} -
- -
-
-
-
- -
-
-
-
-
-
- -
-
-
@@ -170,245 +104,219 @@ + + + {% endblock %} {% block scripts %} {{ super() }} + diff --git a/eveai_app/templates/scripts.html b/eveai_app/templates/scripts.html index 1397bd8..f298616 100644 --- a/eveai_app/templates/scripts.html +++ b/eveai_app/templates/scripts.html @@ -122,21 +122,41 @@ function validateTableSelection(formId) { }