Repository: urlaubsverwaltung/urlaubsverwaltung (java)

Issue:
Fehlende Abteilungen unter Konto -> Berechtigungen
Abteilungen in denen der Benutzenden nur zugehörig ist, also kein Abteilungsleiter oder Freigabe-Verantwortlicher, werden nicht angezeigt.

In der Übersicht:

![grafik](https://github.com/user-attachments/assets/f2699c96-f27a-497c-b06e-66c3b62f8614)

Unter Konto -> Berechtigungen

![grafik](https://github.com/user-attachments/assets/4026be55-4ac9-44c4-a01b-4c7a889fc146)


Pull request description:
Fix missing departments in permissions details
closes #4792 

Patch:
diff --git a/src/main/java/org/synyx/urlaubsverwaltung/person/web/PersonPermissionsViewController.java b/src/main/java/org/synyx/urlaubsverwaltung/person/web/PersonPermissionsViewController.java
index e4e83c64e..d39cc8647 100644
--- a/src/main/java/org/synyx/urlaubsverwaltung/person/web/PersonPermissionsViewController.java
+++ b/src/main/java/org/synyx/urlaubsverwaltung/person/web/PersonPermissionsViewController.java
@@ -65,7 +65,8 @@ public class PersonPermissionsViewController implements HasLaunchpad {
         final Person person = personService.getPersonByID(personId).orElseThrow(() -> new UnknownPersonException(personId));
 
         model.addAttribute("person", mapToPersonPermissionsDto(person));
-        model.addAttribute("departments", departmentService.getManagedDepartmentsOfDepartmentHead(person));
+        model.addAttribute("departments", departmentService.getAssignedDepartmentsOfMember(person));
+        model.addAttribute("departmentHeadDepartments", departmentService.getManagedDepartmentsOfDepartmentHead(person));
         model.addAttribute("secondStageDepartments", departmentService.getManagedDepartmentsOfSecondStageAuthority(person));
 
         return "person/person_permissions";
diff --git a/src/main/resources/templates/person/person_permissions.html b/src/main/resources/templates/person/person_permissions.html
index d3fe21c52..a318600f1 100644
--- a/src/main/resources/templates/person/person_permissions.html
+++ b/src/main/resources/templates/person/person_permissions.html
@@ -74,19 +74,32 @@
                       <input type="checkbox" th:field="*{permissions}" value="DEPARTMENT_HEAD" />
                       <th:block th:text="#{person.form.permissions.roles.DEPARTMENT_HEAD.description}" />
                     </label>
-                    <label th:class="|tw-leading-snug ${not #lists.isEmpty(departments) ? 'info' : ''}|">
+                    <div class="tw-ml-6 tw-text-sm tw-leading-snug">
                       <svg th:replace="~{icon/info::svg(className='tw-w-4 tw-h-4')}"></svg>
                       <th:block
-                        th:if="${#lists.isEmpty(departments)}"
+                        th:if="${#lists.isEmpty(departmentHeadDepartments)}"
                         th:text="#{person.form.permissions.roles.DEPARTMENT_HEAD.departments.none.description}"
                       />
-                      <th:block th:if="${not #lists.isEmpty(departments)}">
+                      <th:block th:if="${not #lists.isEmpty(departmentHeadDepartments)}">
                         <th:block th:text="#{person.form.permissions.roles.DEPARTMENT_HEAD.departments.description}" />
-                        <th:block th:each="department, loop : ${departments}">
-                          <th:block th:text="|${department.name}${!loop.last ? ',' : ''}|" />
-                        </th:block>
+                        <ul
+                          th:if="${departmentHeadDepartments != null && not #lists.isEmpty(departmentHeadDepartments)}"
+                          class="tw-mt-1.5 tw-m-0 tw-p-0 tw-list-none tw-flex tw-flex-wrap tw-text-xs tw-gap-1"
+                          th:aria-label="#{person.form.permissions.roles.DEPARTMENT_HEAD.departments.description}"
+                        >
+                          <li th:each="department : ${departmentHeadDepartments}">
+                            <a
+                              href="#"
+                              th:href="@{/web/absences (department=${department.name})}"
+                              th:text="${department.name}"
+                              class="tw-px-1.5 tw-no-underline tw-rounded-full tw-bg-emerald-100 tw-text-emerald-800 dark:tw-border dark:tw-border-green-600 dark:tw-text-green-600 dark:tw-bg-transparent print:no-link"
+                            >
+                              Geschäftsführung
+                            </a>
+                          </li>
+                        </ul>
                       </th:block>
-                    </label>
+                    </div>
                   </div>
 
                   <div class="checkbox tw-pb-2 tw-mb-2">
@@ -98,7 +111,7 @@
                       <input type="checkbox" th:field="*{permissions}" value="SECOND_STAGE_AUTHORITY" />
                       <th:block th:text="#{person.form.permissions.roles.SECOND_STAGE_AUTHORITY.description}" />
                     </label>
-                    <label th:class="|tw-leading-snug ${not #lists.isEmpty(secondStageDepartments) ? 'info' : ''}|">
+                    <div class="tw-ml-6 tw-text-sm tw-leading-snug">
                       <svg th:replace="~{icon/info::svg(className='tw-w-4 tw-h-4')}"></svg>
                       <th:block
                         th:if="${#lists.isEmpty(secondStageDepartments)}"
@@ -108,11 +121,24 @@
                         <th:block
                           th:text="#{person.form.permissions.roles.SECOND_STAGE_AUTHORITY.departments.description}"
                         />
-                        <th:block th:each="department, loop : ${secondStageDepartments}">
-                          <th:block th:text="|${department.name}${!loop.last ? ',' : ''}|" />
-                        </th:block>
+                        <ul
+                          th:if="${secondStageDepartments != null && not #lists.isEmpty(secondStageDepartments)}"
+                          class="tw-mt-1.5 tw-m-0 tw-p-0 tw-list-none tw-flex tw-flex-wrap tw-text-xs tw-gap-1"
+                          th:aria-label="#{person.form.permissions.roles.DEPARTMENT_HEAD.departments.description}"
+                        >
+                          <li th:each="department : ${secondStageDepartments}">
+                            <a
+                              href="#"
+                              th:href="@{/web/absences (department=${department.name})}"
+                              th:text="${department.name}"
+                              class="tw-px-1.5 tw-no-underline tw-rounded-full tw-bg-emerald-100 tw-text-emerald-800 dark:tw-border dark:tw-border-green-600 dark:tw-text-green-600 dark:tw-bg-transparent print:no-link"
+                            >
+                              Geschäftsführung
+                            </a>
+                          </li>
+                        </ul>
                       </th:block>
-                    </label>
+                    </div>
                   </div>
 
                   <div class="checkbox tw-pb-2 tw-mb-2">


Test patch:
diff --git a/src/test/java/org/synyx/urlaubsverwaltung/person/web/PersonPermissionsViewControllerTest.java b/src/test/java/org/synyx/urlaubsverwaltung/person/web/PersonPermissionsViewControllerTest.java
index 6b3922026..db160400d 100644
--- a/src/test/java/org/synyx/urlaubsverwaltung/person/web/PersonPermissionsViewControllerTest.java
+++ b/src/test/java/org/synyx/urlaubsverwaltung/person/web/PersonPermissionsViewControllerTest.java
@@ -90,13 +90,16 @@ class PersonPermissionsViewControllerTest {
         when(personService.getPersonByID(1L)).thenReturn(Optional.of(person));
 
         final List<Department> departments = List.of(new Department());
+        final List<Department> departmentHeadDepartments = List.of(new Department());
         final List<Department> secondStageDepartments = List.of(new Department());
 
-        when(departmentService.getManagedDepartmentsOfDepartmentHead(any())).thenReturn(departments);
+        when(departmentService.getAssignedDepartmentsOfMember(any())).thenReturn(departments);
+        when(departmentService.getManagedDepartmentsOfDepartmentHead(any())).thenReturn(departmentHeadDepartments);
         when(departmentService.getManagedDepartmentsOfSecondStageAuthority(any())).thenReturn(secondStageDepartments);
 
         perform(get("/web/person/1/permissions"))
             .andExpect(model().attribute("departments", departments))
+            .andExpect(model().attribute("departmentHeadDepartments", departmentHeadDepartments))
             .andExpect(model().attribute("secondStageDepartments", secondStageDepartments));
     }