gitshark

Clone repository

git clone https://gitshark.de/git/workaround/Gitshark.git
git clone git@gitshark.de:workaround/Gitshark.git

← Commits

✨ (orgs): List organisation memberships on the dashboard

6137fe48f4c483085e187a89a9206954a737253b · Michael Hainz · 2026-07-10T06:54:31Z

Changes

6 files changed, +45 -2

MODIFY docs/users/organisations.md +3 -0
diff --git a/docs/users/organisations.md b/docs/users/organisations.md
index 016efe2..4a3075b 100644
--- a/docs/users/organisations.md
+++ b/docs/users/organisations.md
@@ -18,6 +18,9 @@
18 18
19 19 You become the organisation's first **owner**.
20 20
21 +Every organisation you belong to (any role) is listed in an **Organisations** section on
22 +your dashboard (`/`), linking to its page at `/orgs/<name>`.
23 +
21 24 ## Member levels
22 25
23 26 | Level | Rights |
MODIFY src/main/java/de/workaround/account/OrganisationService.java +6 -0
diff --git a/src/main/java/de/workaround/account/OrganisationService.java b/src/main/java/de/workaround/account/OrganisationService.java
index 666ef91..1f4197d 100644
--- a/src/main/java/de/workaround/account/OrganisationService.java
+++ b/src/main/java/de/workaround/account/OrganisationService.java
@@ -131,6 +131,12 @@
131 131 return members.findByOrganisation(organisation);
132 132 }
133 133
134 + /** All memberships of the user, any role — drives the dashboard's organisation list. */
135 + public List<OrganisationMember> membershipsOf(User user)
136 + {
137 + return members.findByUser(user);
138 + }
139 +
134 140 /** Organisations in which the user holds the OWNER role — the ones they may create repositories in. */
135 141 public List<Organisation> ownedBy(User user)
136 142 {
MODIFY src/main/java/de/workaround/model/OrganisationMember.java +3 -0
diff --git a/src/main/java/de/workaround/model/OrganisationMember.java b/src/main/java/de/workaround/model/OrganisationMember.java
index 6707b80..2ebcb56 100644
--- a/src/main/java/de/workaround/model/OrganisationMember.java
+++ b/src/main/java/de/workaround/model/OrganisationMember.java
@@ -67,6 +67,9 @@
67 67 @HQL("where organisation = :organisation order by user.username")
68 68 List<OrganisationMember> findByOrganisation(Organisation organisation);
69 69
70 + @HQL("where user = :user order by organisation.name")
71 + List<OrganisationMember> findByUser(User user);
72 +
70 73 @HQL("where user = :user and role = OWNER order by organisation.name")
71 74 List<OrganisationMember> findOwnerships(User user);
72 75
MODIFY src/main/java/de/workaround/web/HomeResource.java +3 -2
diff --git a/src/main/java/de/workaround/web/HomeResource.java b/src/main/java/de/workaround/web/HomeResource.java
index 2dccf64..831ea94 100644
--- a/src/main/java/de/workaround/web/HomeResource.java
+++ b/src/main/java/de/workaround/web/HomeResource.java
@@ -41,7 +41,7 @@
41 41 static native TemplateInstance home(List<Repository> repositories, User user);
42 42
43 43 static native TemplateInstance dashboard(List<Repository> pinned, List<NotificationItem> notifications,
44 - List<DashboardRepo> repositories, User user);
44 + List<DashboardRepo> repositories, List<OrganisationMember> orgs, User user);
45 45
46 46 static native TemplateInstance landing();
47 47
@@ -81,7 +81,8 @@
81 81 List<DashboardRepo> rows = service.listVisibleTo(user).stream()
82 82 .map(repo -> new DashboardRepo(repo, pinnedIds.contains(repo.id)))
83 83 .toList();
84 - return Templates.dashboard(pinned, notifications.notificationsFor(user), rows, user);
84 + return Templates.dashboard(pinned, notifications.notificationsFor(user), rows,
85 + organisations.membershipsOf(user), user);
85 86 }
86 87
87 88 @GET
MODIFY src/main/resources/templates/HomeResource/dashboard.html +15 -0
diff --git a/src/main/resources/templates/HomeResource/dashboard.html b/src/main/resources/templates/HomeResource/dashboard.html
index 1277adb..44d049d 100644
--- a/src/main/resources/templates/HomeResource/dashboard.html
+++ b/src/main/resources/templates/HomeResource/dashboard.html
@@ -27,6 +27,21 @@
27 27 {/if}
28 28 </section>
29 29
30 +{#if !orgs.isEmpty()}
31 +<section class="dashboard-section">
32 + <h2>Organisations</h2>
33 + <table>
34 + <tr><th>Organisation</th><th>Your role</th></tr>
35 + {#for membership in orgs}
36 + <tr>
37 + <td><span class="av-fallback">{membership.organisation.name.charAt(0)}</span> <a class="mono" href="/orgs/{membership.organisation.name}">{membership.organisation.name}</a></td>
38 + <td><span class="badge">{membership.role.name().toLowerCase()}</span></td>
39 + </tr>
40 + {/for}
41 + </table>
42 +</section>
43 +{/if}
44 +
30 45 <section class="dashboard-section">
31 46 <h2>Notifications</h2>
32 47 {#if notifications.isEmpty()}
MODIFY src/test/java/de/workaround/web/OrganisationUiTest.java +15 -0
diff --git a/src/test/java/de/workaround/web/OrganisationUiTest.java b/src/test/java/de/workaround/web/OrganisationUiTest.java
index a7eb905..848b98e 100644
--- a/src/test/java/de/workaround/web/OrganisationUiTest.java
+++ b/src/test/java/de/workaround/web/OrganisationUiTest.java
@@ -263,6 +263,21 @@
263 263
264 264 @Test
265 265 @TestSecurity(user = MEMBER)
266 + void dashboardListsOrganisationsTheUserBelongsTo()
267 + {
268 + User creator = persistUser(CREATOR);
269 + User member = persistUser(MEMBER);
270 + Organisation org = createOrg(creator);
271 + addMember(creator, org, member, OrganisationMember.Role.MEMBER);
272 +
273 + given()
274 + .when().get("/")
275 + .then().statusCode(200)
276 + .body(containsString("/orgs/" + org.name));
277 + }
278 +
279 + @Test
280 + @TestSecurity(user = MEMBER)
266 281 void orgRepositoryAppearsOnMemberDashboard()
267 282 {
268 283 User creator = persistUser(CREATOR);

Keyboard shortcuts

?Show this help
g hGo home
EscClose dialog