From fac5b7e3d557193740808cd5edc79ceb4bada339 Mon Sep 17 00:00:00 2001 From: Mathilde Kaploun Date: Tue, 5 May 2026 17:43:58 +0200 Subject: [PATCH 01/41] feat: reset tree visual selection state on change tab (Element/Template) --- js/pi-system_treecontroller.js | 38 ++-------------------------------- 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/js/pi-system_treecontroller.js b/js/pi-system_treecontroller.js index aee05d8..b2aa0d9 100644 --- a/js/pi-system_treecontroller.js +++ b/js/pi-system_treecontroller.js @@ -133,10 +133,7 @@ app.controller('AfExplorerFormCtrl', [ $scope.config.outputSelectedAttributes = $scope.config.outputSelectedAttributes || []; // la liste des attributs qui sont séléctionnés pour être dans l'output dataset $scope.config.searchMatchedElementPaths = $scope.config.searchMatchedElementPaths || []; // la liste pour highlighter les elements de la recherche $scope.config.lastSearchedElementName = $scope.config.lastSearchedElementName || ""; - $scope.config.pendingTabContextReset = $scope.config.pendingTabContextReset || false; // indique le changement de tab template/element $scope.config.selectedTemplateNames = $scope.config.selectedTemplateNames || []; // la liste des templates sélectionnés (checkbox cochée) parmi ceux affichés - $scope.config.selectAllWithoutTemplateAttributes = $scope.config.selectAllWithoutTemplateAttributes || false; // select all des attributs standalone - $scope.config.selectAllTemplateAttributes = $scope.config.selectAllTemplateAttributes || false; // select all des attributs groupés par template $scope.aggregateDataTypeFields = aggregateDataTypeFields; $scope.attributeGroupSections = [ @@ -266,7 +263,6 @@ app.controller('AfExplorerFormCtrl', [ $scope.config.outputSelectedAttributes = []; $scope.config.searchMatchedElementPaths = []; $scope.config.lastSearchedElementName = ""; - $scope.config.pendingTabContextReset = false; $scope.config.selectedTemplateNames = []; $scope.config.selectAllWithoutTemplateAttributes = false; $scope.config.selectAllTemplateAttributes = false; @@ -406,18 +402,10 @@ app.controller('AfExplorerFormCtrl', [ } } - function consumePendingTabContextReset() { // reset la main view après changement de tab + action sur le new tab - if (!$scope.config.pendingTabContextReset) { - return; - } - resetRightPanelForCurrentTabContext(); - $scope.config.pendingTabContextReset = false; - } - $scope.setTab = function(tab) { const previousTab = $scope.config.activeTab; if (tab !== previousTab) { - $scope.config.pendingTabContextReset = true; + resetRightPanelForCurrentTabContext(); } $scope.config.activeTab = tab; }; @@ -437,7 +425,6 @@ app.controller('AfExplorerFormCtrl', [ } $scope.doSearch = function(element_name, attribute_name) { - consumePendingTabContextReset(); const hasElementFilter = !!(element_name?.trim()); const hadPreviousElementFilter = !!($scope.config.lastSearchedElementName?.trim()); @@ -751,7 +738,7 @@ app.controller('AfExplorerFormCtrl', [ // TODO: check this makes sense, since selectedOutput is persisted and so newly loaded attributes should not be found in it const selectedAttribute = $scope.config.outputSelectedAttributes.find(attr => attr.path === attribute.path); attribute.checked = !!(selectedAttribute); - attribute.parent_element = parentNode.title; + attribute.parent_element = parentNode?.title; attribute.data_type = selectedAttribute?.data_type ? selectedAttribute.data_type : $scope.aggregateDataTypeFields.data_type.defaultValue; Object.entries($scope.aggregateDataTypeFields.aggregates).forEach(([aggregateName, aggregate]) => { if ((selectedAttribute?.[aggregateName] === undefined || selectedAttribute?.[aggregateName] === null) && aggregate.isVisible(attribute)) { @@ -1048,26 +1035,6 @@ app.component('treeNode', { controller: function() { const ctrl = this; - function consumePendingTabContextReset() { - if (!ctrl.config?.pendingTabContextReset) { - return; - } - - ctrl.config.attribute_name = ""; - ctrl.config.clickedNodes = []; - ctrl.config.attributeList = []; - ctrl.config.selectAllWithoutTemplateAttributes = false; - ctrl.config.selectAllTemplateAttributes = false; - ctrl.config.searchMatchedElementPaths = []; - - if (ctrl.config.activeTab === "element") { - ctrl.config.template = "-- Any --"; - } else if (ctrl.config.activeTab === "template") { - ctrl.config.element_name = ""; - } - - ctrl.config.pendingTabContextReset = false; - } function findNodeByUrl(nodes, targetUrl) { if (!Array.isArray(nodes) || !targetUrl) { @@ -1139,7 +1106,6 @@ app.component('treeNode', { }; ctrl.onNodeClick = function(node) { - consumePendingTabContextReset(); // TODO: factorize this check const hasActiveAttributeSearch = !!( From 3e34dca92753b08c1a2a615a551a08c2cbde7dc4 Mon Sep 17 00:00:00 2001 From: Mathilde Kaploun Date: Sat, 9 May 2026 13:59:57 +0200 Subject: [PATCH 02/41] feat: attribute search (empty sections still show) --- js/pi-system_treecontroller.js | 12 ++++++++++++ resource/pi-system_af-explorer.html | 22 +++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/js/pi-system_treecontroller.js b/js/pi-system_treecontroller.js index f89b757..9393e9f 100644 --- a/js/pi-system_treecontroller.js +++ b/js/pi-system_treecontroller.js @@ -134,6 +134,7 @@ app.controller('AfExplorerFormCtrl', [ $scope.config.searchMatchedElementPaths = $scope.config.searchMatchedElementPaths || []; // la liste pour highlighter les elements de la recherche $scope.config.lastSearchedElementName = $scope.config.lastSearchedElementName || ""; $scope.config.selectedTemplateNames = $scope.config.selectedTemplateNames || []; // la liste des templates sélectionnés (checkbox cochée) parmi ceux affichés + $scope.config.attributeSearch = $scope.config.attributeSearch || ""; $scope.aggregateDataTypeFields = aggregateDataTypeFields; $scope.attributeGroupSections = [ @@ -803,6 +804,12 @@ app.controller('AfExplorerFormCtrl', [ }); }; + function attributeMatchesSearch(attribute_name, template_name) { + const templateNameMatches = template_name.toLowerCase().includes($scope.config.attributeSearch.toLowerCase()); + const attributeNameMatches = attribute_name.toLowerCase().includes($scope.config.attributeSearch.toLowerCase()); + return (templateNameMatches || attributeNameMatches) + } + function groupDuplicatedAttributesAcrossGroup(groupKey) { return (acc, attr) => { // TODO: switch to id @@ -822,6 +829,7 @@ app.controller('AfExplorerFormCtrl', [ paths: [], data_type: attr.data_type, data_types: [], + matchesSearch: attributeMatchesSearch(attr.title, attr[groupKey]), }; getAggregateNames().forEach(aggregateName => { @@ -940,6 +948,10 @@ app.controller('AfExplorerFormCtrl', [ $scope.groupedAttributes = $scope.buildGroupedAttributes(); }, true); + $scope.refreshAttributeSection = function() { + $scope.groupedAttributes = $scope.buildGroupedAttributes(); + } + function attributeMatchesCurrentSearch(attribute) { const rawFilter = ($scope.config.attribute_name || "").trim(); diff --git a/resource/pi-system_af-explorer.html b/resource/pi-system_af-explorer.html index b01977b..7bbed87 100644 --- a/resource/pi-system_af-explorer.html +++ b/resource/pi-system_af-explorer.html @@ -79,20 +79,15 @@