From 7721361433f0eb6e81951bd4ffecd49629c84065 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Tue, 8 Sep 2026 11:20:23 +0200
Subject: [PATCH 1/9] [NAE-2472] Menu Item improvements - fix cyclic path
detection - remove URI destination fields from menu item creation form
---
.../engine/menu/utils/MenuItemUtils.java | 5 +-
.../engine-processes/menu/menu_item.xml | 43 --------------
.../engine/menu/MenuItemUtilsTest.java | 56 +++++++++++++++++++
3 files changed, 60 insertions(+), 44 deletions(-)
create mode 100644 src/test/java/com/netgrif/application/engine/menu/MenuItemUtilsTest.java
diff --git a/src/main/java/com/netgrif/application/engine/menu/utils/MenuItemUtils.java b/src/main/java/com/netgrif/application/engine/menu/utils/MenuItemUtils.java
index b7b3107a8b..a899f69815 100644
--- a/src/main/java/com/netgrif/application/engine/menu/utils/MenuItemUtils.java
+++ b/src/main/java/com/netgrif/application/engine/menu/utils/MenuItemUtils.java
@@ -92,7 +92,10 @@ public static String findTaskIdInCase(Case useCase, String transId) {
* */
public static boolean isCyclicNodePath(Case folderItem, String destUri) {
String oldNodePath = (String) folderItem.getFieldValue(MenuItemConstants.FIELD_NODE_PATH);
- return oldNodePath != null && destUri.contains(oldNodePath);
+ if (oldNodePath == null || destUri == null) {
+ return false;
+ }
+ return destUri.contains(oldNodePath + "/") || destUri.endsWith(oldNodePath);
}
/**
diff --git a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
index 01b2dc56b0..f01ccc8a69 100644
--- a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
@@ -873,49 +873,6 @@
-
- move_dest_uri
-
- editable
- required
-
-
- 0
- 1
- 1
- 2
- material
- outline
-
-
-
- move_dest_uri_new_node
-
- editable
-
-
- 2
- 1
- 1
- 1
- material
- outline
-
-
-
- move_add_node
-
- editable
-
-
- 3
- 1
- 1
- 1
- material
- outline
-
-
configuration_templates
diff --git a/src/test/java/com/netgrif/application/engine/menu/MenuItemUtilsTest.java b/src/test/java/com/netgrif/application/engine/menu/MenuItemUtilsTest.java
new file mode 100644
index 0000000000..8f6cbd3899
--- /dev/null
+++ b/src/test/java/com/netgrif/application/engine/menu/MenuItemUtilsTest.java
@@ -0,0 +1,56 @@
+package com.netgrif.application.engine.menu;
+
+import com.netgrif.application.engine.menu.domain.MenuItemConstants;
+import com.netgrif.application.engine.menu.utils.MenuItemUtils;
+import com.netgrif.application.engine.workflow.domain.Case;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@SpringBootTest
+@ActiveProfiles({"test"})
+@ExtendWith(SpringExtension.class)
+public class MenuItemUtilsTest {
+
+ @Test
+ public void testIsCyclicNodePath_withCyclicPath_returnsTrue() {
+ Case folderItem = mock(Case.class);
+
+ when(folderItem.getFieldValue(MenuItemConstants.FIELD_NODE_PATH)).thenReturn("/node1/node2");
+ boolean result = MenuItemUtils.isCyclicNodePath(folderItem, "/node1/node2/node3");
+ assertTrue(result);
+
+ when(folderItem.getFieldValue(MenuItemConstants.FIELD_NODE_PATH)).thenReturn("/node1/node2");
+ result = MenuItemUtils.isCyclicNodePath(folderItem, "/node4/node1/node2/node3");
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsCyclicNodePath_withNonCyclicPath_returnsFalse() {
+ Case folderItem = mock(Case.class);
+
+ when(folderItem.getFieldValue(MenuItemConstants.FIELD_NODE_PATH)).thenReturn("/node1/node2");
+ boolean result = MenuItemUtils.isCyclicNodePath(folderItem, "/node3/node4");
+ assertFalse(result);
+
+ when(folderItem.getFieldValue(MenuItemConstants.FIELD_NODE_PATH)).thenReturn("/node1/node2");
+ result = MenuItemUtils.isCyclicNodePath(folderItem, null);
+ assertFalse(result);
+
+ when(folderItem.getFieldValue(MenuItemConstants.FIELD_NODE_PATH)).thenReturn("/node1/node2");
+ result = MenuItemUtils.isCyclicNodePath(folderItem, "/node1/node2_2/node3");
+ assertFalse(result);
+
+
+ when(folderItem.getFieldValue(MenuItemConstants.FIELD_NODE_PATH)).thenReturn(null);
+ result = MenuItemUtils.isCyclicNodePath(folderItem, "/node1/node2");
+ assertFalse(result);
+ }
+
+}
From bbe2a8f61aa253b4d37265193f9698ad26a5ed28 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Tue, 8 Sep 2026 11:43:44 +0200
Subject: [PATCH 2/9] [NAE-2472] Menu Item improvements - add ordering to
configuration templates - make configuration template data field autocomplete
---
.../menu/service/MenuItemTemplateHolder.java | 28 +++++++++++--------
.../engine-processes/menu/menu_item.xml | 3 ++
2 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/src/main/java/com/netgrif/application/engine/menu/service/MenuItemTemplateHolder.java b/src/main/java/com/netgrif/application/engine/menu/service/MenuItemTemplateHolder.java
index c3573264c2..8037e245da 100644
--- a/src/main/java/com/netgrif/application/engine/menu/service/MenuItemTemplateHolder.java
+++ b/src/main/java/com/netgrif/application/engine/menu/service/MenuItemTemplateHolder.java
@@ -5,6 +5,7 @@
import com.netgrif.application.engine.menu.utils.MenuItemUtils;
import com.netgrif.application.engine.petrinet.domain.I18nString;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -26,16 +27,19 @@ public class MenuItemTemplateHolder {
* The key is the template identifier (String), and the value is the Template instance.
*
*/
- private final static Map templates = Map.of(
- TabbedCaseViewTemplate.IDENTIFIER, new TabbedCaseViewTemplate(),
- TabbedTaskViewTemplate.IDENTIFIER, new TabbedTaskViewTemplate(),
- SimpleCaseViewTemplate.IDENTIFIER, new SimpleCaseViewTemplate(),
- SimpleTaskViewTemplate.IDENTIFIER, new SimpleTaskViewTemplate(),
- SingleTaskViewTemplate.IDENTIFIER, new SingleTaskViewTemplate(),
- TabbedTicketViewTemplate.IDENTIFIER, new TabbedTicketViewTemplate(),
- CustomViewTemplate.IDENTIFIER, new CustomViewTemplate(),
- FolderTemplate.IDENTIFIER, new FolderTemplate()
- );
+ private final static Map templates;
+
+ static {
+ templates = new LinkedHashMap<>();
+ templates.put(FolderTemplate.IDENTIFIER, new FolderTemplate());
+ templates.put(TabbedCaseViewTemplate.IDENTIFIER, new TabbedCaseViewTemplate());
+ templates.put(TabbedTaskViewTemplate.IDENTIFIER, new TabbedTaskViewTemplate());
+ templates.put(SimpleCaseViewTemplate.IDENTIFIER, new SimpleCaseViewTemplate());
+ templates.put(SimpleTaskViewTemplate.IDENTIFIER, new SimpleTaskViewTemplate());
+ templates.put(SingleTaskViewTemplate.IDENTIFIER, new SingleTaskViewTemplate());
+ templates.put(TabbedTicketViewTemplate.IDENTIFIER, new TabbedTicketViewTemplate());
+ templates.put(CustomViewTemplate.IDENTIFIER, new CustomViewTemplate());
+ }
/**
@@ -116,7 +120,9 @@ public static Map transformToOptions() {
return templates.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
- entry -> entry.getValue().getName()
+ entry -> entry.getValue().getName(),
+ (a, b) -> a,
+ LinkedHashMap::new
));
}
}
diff --git a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
index f01ccc8a69..93bf8a640e 100644
--- a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
@@ -665,6 +665,9 @@
com.netgrif.application.engine.menu.service.MenuItemTemplateHolder.transformToOptions()
+
+ autocomplete
+
From 1057128399dff2b4f0904123cc98736ebdddd5e8 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Tue, 8 Sep 2026 12:53:15 +0200
Subject: [PATCH 3/9] [NAE-2472] Menu Item improvements - update behavior logic
and texts in menu item processes
---
.../menu/case_view_configuration.xml | 49 +++++++++++++++----
.../engine-processes/menu/menu_item.xml | 28 +++++------
.../menu/task_view_configuration.xml | 1 -
3 files changed, 52 insertions(+), 26 deletions(-)
diff --git a/src/main/resources/petriNets/engine-processes/menu/case_view_configuration.xml b/src/main/resources/petriNets/engine-processes/menu/case_view_configuration.xml
index 77bf89b0f7..b56e6604b1 100644
--- a/src/main/resources/petriNets/engine-processes/menu/case_view_configuration.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/case_view_configuration.xml
@@ -534,7 +534,7 @@
case_show_more_menu
editable
-
+
1
0
@@ -562,7 +562,7 @@
case_empty_content_text
editable
-
+
0
1
@@ -576,7 +576,7 @@
case_empty_content_icon
editable
-
+
1
1
@@ -590,7 +590,7 @@
case_empty_content_icon_preview
visible
-
+
2
1
@@ -604,7 +604,7 @@
case_all_allowed_nets
editable
-
+
0
2
@@ -613,11 +613,25 @@
material
outline
+
+ 0
+
+
+ trans: t.this,
+ case_all_allowed_nets: f.case_all_allowed_nets,
+ case_allowed_nets: f.case_allowed_nets,
+ case_inherit_allowed_nets: f.case_inherit_allowed_nets;
+
+ make [case_allowed_nets, case_inherit_allowed_nets], hidden on trans when { case_all_allowed_nets.value }
+ make [case_allowed_nets, case_inherit_allowed_nets], editable on trans when { !case_all_allowed_nets.value }
+
+
+
case_allowed_nets
- editable
+ hidden
1
@@ -631,8 +645,8 @@
case_inherit_allowed_nets
- editable
-
+ hidden
+
2
2
@@ -828,6 +842,24 @@
material
outline
+
+ 0
+
+
+ trans: t.this,
+ show_create_case_button: f.show_create_case_button,
+ require_title_in_creation: f.require_title_in_creation,
+ create_case_button_title: f.create_case_button_title,
+ create_case_button_icon: f.create_case_button_icon,
+ create_case_button_icon_preview: f.create_case_button_icon_preview,
+ banned_nets_in_creation: f.banned_nets_in_creation;
+
+ make [require_title_in_creation, create_case_button_title, create_case_button_icon, create_case_button_icon_preview, banned_nets_in_creation], hidden on trans when { !show_create_case_button.value }
+ make [require_title_in_creation, create_case_button_title, create_case_button_icon, banned_nets_in_creation], editable on trans when { show_create_case_button.value }
+ make create_case_button_icon_preview, visible on trans when { show_create_case_button.value }
+
+
+
require_title_in_creation
@@ -1063,7 +1095,6 @@
case_headers_sort_mode_active
editable
- required
0
diff --git a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
index 93bf8a640e..6426ae1b4f 100644
--- a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
@@ -299,7 +299,7 @@
menu_icon
Menu icon identifier
- Material icon identifier. List of icons with identifiers is available online.
+ Material icon identifier
icon: f.this,
iconPreview: f.menu_icon_preview;
@@ -326,7 +326,6 @@
menu_name_as_visible
Name of the item
- Will be shown in the menu
autocomplete
@@ -334,7 +333,6 @@
menu_name
Name of the item
- Will be shown in the menu
menu_name_as_visible: f.menu_name_as_visible,
name: f.menu_name;
@@ -502,7 +500,7 @@
tab_icon
Tab icon identifier
- Material icon identifier. List of icons with identifiers is available online.
+ Material icon identifier
icon: f.this,
iconPreview: f.tab_icon_preview;
@@ -674,7 +672,7 @@
Náhľad ikony
Identifikátor ikony
- Identifikátor Material ikony. Zoznam ikon s identifikátormi je dostupný online.
+ Identifikátor Material ikony.
Pridaj k povoleným roliam
Odstráň z povolených rolí
Pridaj k zakázaným roliam
@@ -687,9 +685,8 @@
Identifikátor duplikovanej položky
Musí byť jedinečný
Názov položky
- Bude zobrazený v menu
Identifikátor ikony v karte
- Identifikátor Material ikony. Zoznam ikon s identifikátormi je dostupný online.
+ Identifikátor Material ikony.
Náhľad ikony v karte
Zobraziť ikonu v karte?
Názov položky
@@ -722,14 +719,14 @@
Zoradiť pod-položky
Vytvoriť menu položku
Konfiguračná šablóna
- Rola
- Zobrazenie
+ Povolenia
+ Zobrazenie v karte
Menu položka
Ikonevorschau
Ikone ID
- Material Ikone ID. Liste den Ikonen mit IDs ist online verfügbar.
+ Material Ikone ID
Zu zulässigen Rollen hinzufügen
Aus zulässigen Rollen entfernen
Zu verbotenen Rollen hinzufügen
@@ -737,7 +734,7 @@
Ihre Prozesse
Wählen Sie einen Prozess mit Rollen aus, die Sie zu Listen mit zulässigen oder verbotenen Rollen hinzufügen möchten.
Verfügbare Rollen
- Material Ikone ID. Liste den Ikonen mit IDs ist online verfügbar.
+ Material Ikone ID
Beispiel: "demo-tabbed-views"
Rollen
Zulässige Rollen
@@ -750,7 +747,6 @@
Identifikator der kopierten Ansicht
Muss einzigartig sein
Titel des Eintrages
- Wird im Menü angezeigt
Ikonen Identifikator der Registerkarte
Vorschau der Registerkarte Ikone
Zeige die Registerkarte Ikone an?
@@ -777,8 +773,8 @@
Untereintrage sortieren
Erstellen
Konfigurationsvorlage
- Rolle
- Ansicht
+ Berechtigungen
+ Ansicht der Registerkarte
Menüeintrag
@@ -1455,7 +1451,7 @@
role_settings
400
48
-
+
person
auto
@@ -1626,7 +1622,7 @@
view_settings
528
48
-
+
image
auto
diff --git a/src/main/resources/petriNets/engine-processes/menu/task_view_configuration.xml b/src/main/resources/petriNets/engine-processes/menu/task_view_configuration.xml
index 0b1ea4c7be..37b6906162 100644
--- a/src/main/resources/petriNets/engine-processes/menu/task_view_configuration.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/task_view_configuration.xml
@@ -706,7 +706,6 @@
task_headers_sort_mode_active
editable
- required
0
From e3bb987e32a26d10d6d829609f45d81a859260cf Mon Sep 17 00:00:00 2001
From: chvostek
Date: Tue, 8 Sep 2026 19:31:04 +0200
Subject: [PATCH 4/9] [NAE-2472] Menu Item improvements - add info text for
item ordering
---
.../engine-processes/menu/menu_item.xml | 57 +++++++++++++++----
1 file changed, 47 insertions(+), 10 deletions(-)
diff --git a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
index 6426ae1b4f..6113b07d91 100644
--- a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
@@ -256,6 +256,20 @@
childItemForms
+
+ empty_child_items_info
+
+
+ new com.netgrif.application.engine.petrinet.domain.I18nString("This menu item has no child items to order.",
+ [sk: "Táto menu položka neobsahuje žiadnu položku na zoradenie", de: "Zu diesem Menüpunkt gibt es keine Untergerichte."])
+
+
+ text
+ true
+ 20
+ true
+
+
is_folder
@@ -1299,30 +1313,53 @@
children_order_0
- 4
+ 3
grid
+
+ empty_child_items_info
+
+ hidden
+
+
+ 1
+ 0
+ 1
+ 1
+ material
+ outline
+
+
childItemForms
editable
-
- forms: f.childItemForms,
- ids: f.childItemIds;
-
- def orderedTaskIds = ids.value?.collect { id -> workflowService.findOne(id).tasks.find { it.transition == "row_for_ordering" }.task }
- change forms value { orderedTaskIds }
-
0
- 0
+ 1
1
- 4
+ 3
material
outline
+
+ assign
+
+
+ trans: t.this,
+ empty_child_items_info: f.empty_child_items_info,
+ forms: f.childItemForms,
+ ids: f.childItemIds;
+
+ def orderedTaskIds = ids.value?.collect { id -> workflowService.findOne(id).tasks.find { it.transition == "row_for_ordering" }.task }
+ make empty_child_items_info, visible on trans when { orderedTaskIds.isEmpty() }
+ make empty_child_items_info, hidden on trans when { !orderedTaskIds.isEmpty() }
+ change forms value { orderedTaskIds }
+
+
+
row_for_ordering
From 0df35df4e198853c40afacd54c9057e2d111c49f Mon Sep 17 00:00:00 2001
From: chvostek
Date: Tue, 8 Sep 2026 19:43:16 +0200
Subject: [PATCH 5/9] [NAE-2472] Menu Item improvements - improve form of
duplicate menu item
---
.../engine-processes/menu/menu_item.xml | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
index 6113b07d91..a51906fa9c 100644
--- a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
@@ -1264,6 +1264,28 @@
material
outline
+
+ 0
+
+
+ duplicate_view_identifier: f.duplicate_view_identifier,
+ duplicate_new_title: f.duplicate_new_title;
+
+ if (duplicate_view_identifier.value != null && !duplicate_view_identifier.value.isEmpty()
+ || duplicate_new_title.value == null) {
+ return
+ }
+
+ String defaultName = duplicate_new_title.value.defaultValue
+ if (defaultName == null || defaultName.isEmpty()) {
+ defaultName = menu_name.value.translations?.values()?.find()
+ }
+
+ String identifier = com.netgrif.application.engine.menu.utils.MenuItemUtils.sanitize(defaultName)
+ change duplicate_view_identifier value { identifier }
+
+
+
duplicate_view_identifier
@@ -1279,6 +1301,27 @@
material
outline
+
+ 0
+
+
+ duplicate_view_identifier: f.duplicate_view_identifier;
+
+ if (menuItemService.existsMenuItem(duplicate_view_identifier.value)) {
+ change duplicate_view_identifier validations { validation('''regex $.^''',
+ new com.netgrif.application.engine.petrinet.domain.I18nString("Such menu item already exists",
+ [sk: "Taká položka menu už existuje", de: "Ein solcher Menüeintrag existiert bereits"]))
+ }
+ } else {
+ change duplicate_view_identifier validations { null }
+ String sanitizedIdentifier = com.netgrif.application.engine.menu.utils.MenuItemUtils.sanitize(duplicate_view_identifier.value)
+ if (duplicate_view_identifier.value != sanitizedIdentifier) {
+ change duplicate_view_identifier value { sanitizedIdentifier }
+ }
+ }
+
+
+
@@ -1289,6 +1332,7 @@
title: f.duplicate_new_title;
duplicateMenuItem(useCase, title.value, identifier.value)
+ Frontend.reloadMenu()
Duplicate
From 3ff4ad0a156b3373ed69803b1eebbc0bf5afa90c Mon Sep 17 00:00:00 2001
From: chvostek
Date: Tue, 8 Sep 2026 19:47:05 +0200
Subject: [PATCH 6/9] [NAE-2472] Menu Item improvements - add icon
configuration when creating item
---
.../engine-processes/menu/menu_item.xml | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
index a51906fa9c..431fb43446 100644
--- a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
@@ -901,6 +901,34 @@
outline
+
+ menu_icon
+
+ editable
+
+
+ 0
+ 3
+ 1
+ 2
+ material
+ outline
+
+
+
+ menu_icon_preview
+
+ visible
+
+
+ 2
+ 3
+ 1
+ 2
+ material
+ standard
+
+
assign
From a20a434da361e0a3f05a8771f33633344d5e23d7 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Wed, 9 Sep 2026 10:21:36 +0200
Subject: [PATCH 7/9] [NAE-2472] Menu Item improvements - add authority
configuration to menu item
---
.../engine/menu/domain/MenuItemBody.java | 6 +--
.../engine/menu/domain/MenuItemConstants.java | 1 +
.../engine-processes/menu/menu_item.xml | 54 +++++++++++++++----
.../engine/menu/MenuItemServiceTest.java | 1 +
4 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/src/main/java/com/netgrif/application/engine/menu/domain/MenuItemBody.java b/src/main/java/com/netgrif/application/engine/menu/domain/MenuItemBody.java
index ea8ef6dd76..3d42b8da67 100644
--- a/src/main/java/com/netgrif/application/engine/menu/domain/MenuItemBody.java
+++ b/src/main/java/com/netgrif/application/engine/menu/domain/MenuItemBody.java
@@ -10,9 +10,7 @@
import lombok.Data;
import lombok.NoArgsConstructor;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* Class, that holds configurable attributes of menu item.
@@ -26,6 +24,7 @@ public class MenuItemBody {
private String menuIcon = "filter_none";
private I18nString menuName;
+ private List allowedAuthorities = List.of("ROLE_USER");
private Map allowedRoles = new HashMap<>();
private Map bannedRoles = new HashMap<>();
private boolean useCustomView = false;
@@ -198,6 +197,7 @@ public ToDataSetOutcome toDataSet(String parentId, String nodePath, Case viewCas
outcome.putDataSetEntry(MenuItemConstants.FIELD_CUSTOM_VIEW_SELECTOR, FieldType.TEXT,
this.customViewSelector);
outcome.putDataSetEntry(MenuItemConstants.FIELD_IS_AUTO_SELECT, FieldType.BOOLEAN, this.isAutoSelect);
+ outcome.putDataSetEntry(MenuItemConstants.FIELD_ALLOWED_AUTHORITIES, FieldType.MULTICHOICE_MAP, this.allowedAuthorities);
outcome.putDataSetEntryOptions(MenuItemConstants.FIELD_ALLOWED_ROLES, FieldType.MULTICHOICE_MAP, this.allowedRoles);
outcome.putDataSetEntryOptions(MenuItemConstants.FIELD_BANNED_ROLES, FieldType.MULTICHOICE_MAP, this.bannedRoles);
outcome.putDataSetEntry(MenuItemConstants.FIELD_CONFIGURATION_TEMPLATES, FieldType.ENUMERATION_MAP, this.configurationTemplateIdentifier);
diff --git a/src/main/java/com/netgrif/application/engine/menu/domain/MenuItemConstants.java b/src/main/java/com/netgrif/application/engine/menu/domain/MenuItemConstants.java
index c4ab1f141c..895f7fc55c 100644
--- a/src/main/java/com/netgrif/application/engine/menu/domain/MenuItemConstants.java
+++ b/src/main/java/com/netgrif/application/engine/menu/domain/MenuItemConstants.java
@@ -9,6 +9,7 @@ public class MenuItemConstants {
public static final String FIELD_IS_FOLDER = "is_folder";
public static final String FIELD_IDENTIFIER = "menu_item_identifier";
public static final String FIELD_APPEND_MENU_ITEM = "append_menu_item_stringId";
+ public static final String FIELD_ALLOWED_AUTHORITIES = "allowed_authorities";
public static final String FIELD_ALLOWED_ROLES = "allowed_roles";
public static final String FIELD_BANNED_ROLES = "banned_roles";
public static final String FIELD_MENU_NAME = "menu_name";
diff --git a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
index 431fb43446..5d46b61d60 100644
--- a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
@@ -469,6 +469,17 @@
[:]
+
+ allowed_authorities
+ Allowed authorities
+ todo 2472
+
+
+
+
+
+ user
+
use_custom_view
Use custom view?
@@ -736,6 +747,11 @@
Povolenia
Zobrazenie v karte
Menu položka
+ todo 2472
+ todo 2472
+ todo 2472
+ todo 2472
+ todo 2472
Ikonevorschau
@@ -790,6 +806,11 @@
Berechtigungen
Ansicht der Registerkarte
Menüeintrag
+ todo 2472
+ todo 2472
+ todo 2472
+ todo 2472
+ todo 2472
@@ -1580,13 +1601,28 @@
3
grid
- processes_available
+ allowed_authorities
editable
0
0
+ 1
+ 3
+ 0
+ material
+ outline
+
+
+
+ processes_available
+
+ editable
+
+
+ 0
+ 1
2
1
0
@@ -1601,7 +1637,7 @@
1
- 0
+ 1
2
1
0
@@ -1616,7 +1652,7 @@
2
- 0
+ 1
1
1
0
@@ -1630,7 +1666,7 @@
2
- 1
+ 2
1
1
0
@@ -1644,7 +1680,7 @@
0
- 2
+ 3
1
3
0
@@ -1658,7 +1694,7 @@
0
- 3
+ 4
1
2
0
@@ -1673,7 +1709,7 @@
2
- 3
+ 4
1
1
0
@@ -1687,7 +1723,7 @@
0
- 4
+ 5
1
2
0
@@ -1702,7 +1738,7 @@
2
- 4
+ 5
1
1
0
diff --git a/src/test/java/com/netgrif/application/engine/menu/MenuItemServiceTest.java b/src/test/java/com/netgrif/application/engine/menu/MenuItemServiceTest.java
index 1f18dc3f42..d7ba08735d 100644
--- a/src/test/java/com/netgrif/application/engine/menu/MenuItemServiceTest.java
+++ b/src/test/java/com/netgrif/application/engine/menu/MenuItemServiceTest.java
@@ -135,6 +135,7 @@ private void createByTemplateAndAssert(MenuItemBody menuItemBody) throws Transit
assertEquals(menuItemBody.isUseTabbedView(), menuItemCase.getFieldValue(MenuItemConstants.FIELD_USE_TABBED_VIEW));
assertEquals(menuItemBody.isUseCustomView(), menuItemCase.getFieldValue(MenuItemConstants.FIELD_USE_CUSTOM_VIEW));
assertEquals(menuItemBody.getConfigurationTemplateIdentifier(), menuItemCase.getFieldValue(MenuItemConstants.FIELD_CONFIGURATION_TEMPLATES));
+ assertEquals(List.of("ROLE_USER"), menuItemCase.getFieldValue(MenuItemConstants.FIELD_ALLOWED_AUTHORITIES));
assertEquals((menuItemBody.getUri() + uriService.getUriSeparator() + menuItemBody.getIdentifier()).replaceAll("//", uriService.getUriSeparator()),
menuItemCase.getFieldValue(MenuItemConstants.FIELD_NODE_PATH));
From cf551d963d4eda9b843d154d70049b9abf3fc680 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Wed, 9 Sep 2026 10:25:40 +0200
Subject: [PATCH 8/9] [NAE-2472] Menu Item improvements - add translations
---
.../engine-processes/menu/menu_item.xml | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
index 5d46b61d60..5a9a15a616 100644
--- a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
@@ -472,7 +472,6 @@
allowed_authorities
Allowed authorities
- todo 2472
@@ -747,11 +746,10 @@
Povolenia
Zobrazenie v karte
Menu položka
- todo 2472
- todo 2472
- todo 2472
- todo 2472
- todo 2472
+ Povolené autority
+ Používateľ
+ Admin
+ Anonymný používateľ
Ikonevorschau
@@ -806,11 +804,10 @@
Berechtigungen
Ansicht der Registerkarte
Menüeintrag
- todo 2472
- todo 2472
- todo 2472
- todo 2472
- todo 2472
+ Zulässige Behörden
+ Benutzer
+ Admin
+ Anonymer Nutzer
From 56a8bd15b96aab21d19260b440de0cf5ca780fe9 Mon Sep 17 00:00:00 2001
From: chvostek
Date: Wed, 9 Sep 2026 11:39:56 +0200
Subject: [PATCH 9/9] [NAE-2472] Menu Item improvements - resolve PR comments
---
.../menu/case_view_configuration.xml | 64 +++++++++----------
.../engine-processes/menu/menu_item.xml | 6 +-
2 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/src/main/resources/petriNets/engine-processes/menu/case_view_configuration.xml b/src/main/resources/petriNets/engine-processes/menu/case_view_configuration.xml
index b56e6604b1..2329ace50e 100644
--- a/src/main/resources/petriNets/engine-processes/menu/case_view_configuration.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/case_view_configuration.xml
@@ -155,6 +155,24 @@
show_create_case_button
Show create case button?
true
+
+ 0
+
+
+ trans: t.create_case_btn_settings,
+ show_create_case_button: f.show_create_case_button,
+ require_title_in_creation: f.require_title_in_creation,
+ create_case_button_title: f.create_case_button_title,
+ create_case_button_icon: f.create_case_button_icon,
+ create_case_button_icon_preview: f.create_case_button_icon_preview,
+ banned_nets_in_creation: f.banned_nets_in_creation;
+
+ make [require_title_in_creation, create_case_button_title, create_case_button_icon, create_case_button_icon_preview, banned_nets_in_creation], hidden on trans when { !show_create_case_button.value }
+ make [require_title_in_creation, create_case_button_title, create_case_button_icon, banned_nets_in_creation], editable on trans when { show_create_case_button.value }
+ make create_case_button_icon_preview, visible on trans when { show_create_case_button.value }
+
+
+
require_title_in_creation
@@ -351,6 +369,20 @@
case_all_allowed_nets
All allowed nets?
true
+
+ 0
+
+
+ trans: t.settings,
+ case_all_allowed_nets: f.case_all_allowed_nets,
+ case_allowed_nets: f.case_allowed_nets,
+ case_inherit_allowed_nets: f.case_inherit_allowed_nets;
+
+ make [case_allowed_nets, case_inherit_allowed_nets], hidden on trans when { case_all_allowed_nets.value }
+ make [case_allowed_nets, case_inherit_allowed_nets], editable on trans when { !case_all_allowed_nets.value }
+
+
+
case_inherit_allowed_nets
@@ -613,20 +645,6 @@
material
outline
-
- 0
-
-
- trans: t.this,
- case_all_allowed_nets: f.case_all_allowed_nets,
- case_allowed_nets: f.case_allowed_nets,
- case_inherit_allowed_nets: f.case_inherit_allowed_nets;
-
- make [case_allowed_nets, case_inherit_allowed_nets], hidden on trans when { case_all_allowed_nets.value }
- make [case_allowed_nets, case_inherit_allowed_nets], editable on trans when { !case_all_allowed_nets.value }
-
-
-
case_allowed_nets
@@ -842,24 +860,6 @@
material
outline
-
- 0
-
-
- trans: t.this,
- show_create_case_button: f.show_create_case_button,
- require_title_in_creation: f.require_title_in_creation,
- create_case_button_title: f.create_case_button_title,
- create_case_button_icon: f.create_case_button_icon,
- create_case_button_icon_preview: f.create_case_button_icon_preview,
- banned_nets_in_creation: f.banned_nets_in_creation;
-
- make [require_title_in_creation, create_case_button_title, create_case_button_icon, create_case_button_icon_preview, banned_nets_in_creation], hidden on trans when { !show_create_case_button.value }
- make [require_title_in_creation, create_case_button_title, create_case_button_icon, banned_nets_in_creation], editable on trans when { show_create_case_button.value }
- make create_case_button_icon_preview, visible on trans when { show_create_case_button.value }
-
-
-
require_title_in_creation
diff --git a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
index 5a9a15a616..3102eb6243 100644
--- a/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
+++ b/src/main/resources/petriNets/engine-processes/menu/menu_item.xml
@@ -477,7 +477,7 @@
- user
+ ROLE_USER
use_custom_view
@@ -1324,7 +1324,7 @@
String defaultName = duplicate_new_title.value.defaultValue
if (defaultName == null || defaultName.isEmpty()) {
- defaultName = menu_name.value.translations?.values()?.find()
+ defaultName = duplicate_new_title.value.translations?.values()?.find()
}
String identifier = com.netgrif.application.engine.menu.utils.MenuItemUtils.sanitize(defaultName)
@@ -1443,7 +1443,7 @@
forms: f.childItemForms,
ids: f.childItemIds;
- def orderedTaskIds = ids.value?.collect { id -> workflowService.findOne(id).tasks.find { it.transition == "row_for_ordering" }.task }
+ def orderedTaskIds = ids.value?.collect { id -> workflowService.findOne(id).tasks.find { it.transition == "row_for_ordering" }.task } ?: []
make empty_child_items_info, visible on trans when { orderedTaskIds.isEmpty() }
make empty_child_items_info, hidden on trans when { !orderedTaskIds.isEmpty() }
change forms value { orderedTaskIds }