diff --git a/src/main/java/nl/tudelft/submit/controller/ModuleController.java b/src/main/java/nl/tudelft/submit/controller/ModuleController.java
index 85f3fc59987b0f2f67382d4f1e5d3ce450b58ed9..08a52f75ceef14170e514719c289f79eb142dc05 100644
--- a/src/main/java/nl/tudelft/submit/controller/ModuleController.java
+++ b/src/main/java/nl/tudelft/submit/controller/ModuleController.java
@@ -17,8 +17,7 @@
  */
 package nl.tudelft.submit.controller;
 
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
@@ -30,8 +29,10 @@ import nl.tudelft.submit.dto.create.DivisionsCreateTypeDTO;
 import nl.tudelft.submit.dto.create.ModuleCreateWithDivisionsDTO;
 import nl.tudelft.submit.dto.create.grading.GradingFormulaCreateDTO;
 import nl.tudelft.submit.dto.create.note.GroupNoteCreateDTO;
+import nl.tudelft.submit.dto.id.GroupId;
 import nl.tudelft.submit.dto.patch.ModulePatchWithDivisionsDTO;
 import nl.tudelft.submit.dto.view.labracore.SubmitAssignmentSummaryDTO;
+import nl.tudelft.submit.dto.view.labracore.SubmitGroupSummaryDTO;
 import nl.tudelft.submit.dto.view.labracore.SubmitModuleViewDTO;
 import nl.tudelft.submit.enums.GradableType;
 import nl.tudelft.submit.security.AuthorizationService;
@@ -73,6 +74,9 @@ public class ModuleController {
 	@Autowired
 	private StatisticsService statisticsService;
 
+	@Autowired
+	private ModuleDivisionService divisionService;
+
 	/**
 	 * Gets the module page.
 	 *
@@ -96,26 +100,61 @@ public class ModuleController {
 	/**
 	 * Gets the groups page for a module
 	 *
-	 * @param  id    the id of the module
-	 * @param  model the model to add details to
-	 * @return       the page to load
+	 * @param  person the authenticated person
+	 * @param  id     the id of the module
+	 * @param  model  the model to add details to
+	 * @return        the page to load
 	 */
 	@GetMapping("/{id}/groups")
 	@PreAuthorize("@authorizationService.hasRoleInModule(#id)")
 	public String getModuleGroups(@AuthenticatedPerson Person person, @PathVariable Long id, Model model) {
 		boolean staff = authService.hasStaffRoleInModule(id);
-		Optional<StudentGroupDetailsDTO> group = groupService.getGroupForPersonInModule(person.getId(), id);
-
-		if (!staff && group.isPresent()) {
-			return "redirect:/group/" + group.get().getId();
-		}
+		ModuleDetailsDTO module = moduleService.getModuleById(id);
 
-		model.addAttribute("module", moduleService.getModuleById(id));
-		model.addAttribute("person", person);
-		model.addAttribute("groupCreate", new StudentGroupCreateDTO().module(new ModuleIdDTO()));
-		model.addAttribute("groups", groupService.showAllGroupsInModule(id, staff));
-		model.addAttribute("note", new GroupNoteCreateDTO(null, null, null));
 		model.addAttribute("staff", staff);
+		model.addAttribute("module", module);
+		model.addAttribute("selfEnroll", editionService
+				.getSubmitEdition(new EditionIdDTO().id(module.getEdition().getId()))
+				.map(e -> true /* TODO e.canStudentsSelfEnroll() */).orElse(false));
+
+		if (staff) {
+
+			List<SubmitGroupSummaryDTO> groups = groupService.showAllGroupsInModule(id, true);
+			List<ModuleDivisionDetailsDTO> divisions = divisionService.getDivisionsByModule(id);
+			Map<Long, Integer> divisionIndices = new HashMap<>();
+			for (int i = 0; i < divisions.size(); i++) {
+				divisionIndices.put(divisions.get(i).getId(), i + 1);
+			}
+
+			model.addAttribute("groups", groups);
+			model.addAttribute("divisions", divisions);
+			model.addAttribute("divisionIndices", divisionIndices);
+			model.addAttribute("note", new GroupNoteCreateDTO(null, new GroupId(), null));
+
+		} else {
+
+			Optional<StudentGroupDetailsDTO> group = groupService.getGroupForPersonInModule(person.getId(),
+					id);
+			if (group.isPresent()) {
+				return "redirect:/group/" + group.get().getId();
+			}
+
+			List<StudentGroupSummaryDTO> allGroups = groupService.getAllGroupsInModule(id);
+			List<ModuleDivisionDetailsDTO> divisions = divisionService.getDivisionsByModule(id);
+			Optional<ModuleDivisionDetailsDTO> division = divisions.parallelStream()
+					.filter(d -> d.getPeople().parallelStream()
+							.anyMatch(p -> p.getId().equals(person.getId())))
+					.findFirst();
+			List<StudentGroupSummaryDTO> groups = division
+					.map(d -> groupService.getAllGroupsInDivision(d.getId()))
+					.orElse(Collections.emptyList());
+			groups.addAll(
+					allGroups.stream().filter(g -> g.getDivision() == null).collect(Collectors.toList()));
+
+			model.addAttribute("groups", groups);
+			model.addAttribute("person", person);
+
+		}
 
 		return "module/groups";
 	}
diff --git a/src/main/java/nl/tudelft/submit/service/StudentGroupService.java b/src/main/java/nl/tudelft/submit/service/StudentGroupService.java
index e9aa9e14988be5d69709c33dfbfb24e5a5d54496..1ce0e52829cd9c2469634df5433d6d966a03b72d 100644
--- a/src/main/java/nl/tudelft/submit/service/StudentGroupService.java
+++ b/src/main/java/nl/tudelft/submit/service/StudentGroupService.java
@@ -159,6 +159,16 @@ public class StudentGroupService {
 		return groupApi.getAllGroupsInModule(moduleId).collectList().block();
 	}
 
+	/**
+	 * Gets all the groups in a division.
+	 *
+	 * @param  divisionId The id of the division
+	 * @return            The list of all groups
+	 */
+	public List<StudentGroupSummaryDTO> getAllGroupsInDivision(Long divisionId) {
+		return groupApi.getAllGroupsInDivision(divisionId).collectList().block();
+	}
+
 	/**
 	 * Gets the SubmitGroup with corresponding id. If it does not exist, creates one.
 	 *
diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties
index 59372174e6583a0e1413409539b6a08c385d6f33..914eff712fbdc0cdb1ae31bd14edb85a2e113bad 100644
--- a/src/main/resources/messages.properties
+++ b/src/main/resources/messages.properties
@@ -152,6 +152,7 @@ module.assignments = Assignments
 module.search_groups = Group / member name
 module.no_group = No group
 module.no_assignments = No assignments
+module.any_division = Any division
 # DivisionsCreateType - enum
 module.create.divisions.NO_ACTION = No changes, keep old structure
 module.create.divisions.JUST_ONE = One division
@@ -206,6 +207,7 @@ group.students_can_create = Students create groups
 group.allow_student_create = Students are allowed to create groups
 group.name_field=Group name
 group.create = Create group
+group.no_division = No division
 
 group.no_members = No members
 group.no_note = No note
diff --git a/src/main/resources/static/css/main.css b/src/main/resources/static/css/main.css
index 12790cddb8f7fa606132caa18004c3d93974dabd..978f07fc4e1d5fbb000f3c0195284172fa483933 100644
--- a/src/main/resources/static/css/main.css
+++ b/src/main/resources/static/css/main.css
@@ -1177,6 +1177,7 @@ a.form-explain {
 
 .list-row-buttons {
     display: flex;
+    justify-self: end;
 }
 
 .list-row-buttons > * + * {
diff --git a/src/main/resources/templates/edition/staff.html b/src/main/resources/templates/edition/staff.html
index 3f9d9b1b54399a05b596b83ded059fd674d48fb0..0d9f8d764066e13ed62e676098bbf3c8053298b9 100644
--- a/src/main/resources/templates/edition/staff.html
+++ b/src/main/resources/templates/edition/staff.html
@@ -138,7 +138,7 @@
                         <span class="center-label" th:text="#{generic.identifier}"></span>
                         <div class="tooltip">
                             <i class="tooltip-icon fas fa-question-circle"></i>
-                            <p class="tooltip-text" th:text="#{assignment.import_participants.identifier_help}"></p>
+                            <p class="tooltip-text" th:text="#{edition.import_participants.identifier_help}"></p>
                         </div>
                     </div>
                     <select id="id-column" th:name="idColumn" class="selectbox" aria-label="Identifier column" disabled></select>
diff --git a/src/main/resources/templates/module/groups.html b/src/main/resources/templates/module/groups.html
index 21c63bbb794c84cbdbc4185cf23302081b3f4d13..5078d42786020ed7ad61326fea3f882ef407f9e0 100644
--- a/src/main/resources/templates/module/groups.html
+++ b/src/main/resources/templates/module/groups.html
@@ -45,27 +45,55 @@
     <div th:if="${!groups.isEmpty() or !staff}" class="boxed-group">
         <div class="list-header">
             <h1 th:text="|#{module.groups}|"></h1>
+            <div th:if="${staff}" th:remove="tag">
+                <a class="button" th:text="#{generic.add}"></a>
+                <button class="button" th:text="#{generic.import}"></button>
+<!--            TODO group create-->
+            </div>
         </div>
-        <div th:if="${staff}" class="list-search">
-            <input id="group-search" type="text" class="textfield" th:placeholder="#{module.search_groups}"
-                   aria-label="Group or member name"
-                   oninput="search('group', ['members'])"/>
+        <div class="list-search">
+            <input id="group-search" type="text" class="textfield" th:placeholder="#{module.search_groups}" aria-label="Group or member name"
+                   oninput="filter('group', ['division'], ['members'])"/>
+            <select th:if="${staff}" id="group-division" class="selectbox" aria-label="Filter on division" onchange="filter('group', ['division'], ['members'])">
+                <option value="all" th:text="#{module.any_division}"></option>
+                <option th:each="division, iter : ${divisions}" th:value="${division.id}" th:text="#{module.division(${divisionIndices[division.id]})}"></option>
+                <option value="-1" th:text="#{group.no_division}"></option>
+            </select>
         </div>
         <div id="group-list" class="list-content">
-            <div th:if="${!staff and groups.isEmpty()}" class="list-row">
-                <span th:text="#{module.no_groups}"></span>
+            <div id="submission-header" class="table-row">
+                <b th:text="#{group.text}"></b>
+                <b th:if="${staff}" th:text="#{module.division.name}"></b>
+                <b></b>
             </div>
-            <div th:each="group : ${groups}" th:id="|group-${group.name}|" class="list-row">
+            <div th:each="group : ${groups}" th:id="|group-${group.name}|" class="table-row">
                 <span th:id="|group-${group.name}-name|" th:text="${group.name}"></span>
-                <span th:if="${staff}" th:id="|group-${group.name}-members|"
-                      th:text="${group.memberUsernames.toString()}" class="hidden"></span>
+                <span th:if="${staff}" th:text="${group.division == null} ? #{group.no_division} : #{module.division(${divisionIndices[group.division.id]})}"></span>
+                <span th:if="${staff}" th:id="|group-${group.name}-division|" th:text="${group?.division?.id} ?: -1" class="hidden"></span>
+                <span th:id="|group-${group.name}-members|" th:text="${group.memberUsernames.toString()}" class="hidden"></span>
                 <div class="list-row-buttons">
-                    <button th:if="${staff}" type="button" class="button" th:text="#{generic.note}"
-                            th:onclick="|toggleOverlay('${group.id}-note-overlay')|"></button>
-                    <a th:if="${staff}" class="button" th:href="@{|/group/${group.id}|}" th:text="#{generic.view}"></a>
                     <form th:unless="${staff}" th:action="@{|/group/${person.id}/join/${group.id}|}" method="post">
-                        <button class="button" type="submit" th:disabled="${group.memberUsernames.size() == group.capacity}" th:text="#{group.join}"></button>
+                        <button type="submit" class="button" th:text="#{group.join}"></button>
                     </form>
+                    <div th:if="${staff}" th:remove="tag">
+                        <button type="button" class="button" th:text="#{generic.note}"
+                                th:onclick="|toggleOverlay('${group.id}-note-overlay')|"></button>
+                        <a class="button" th:href="@{|/group/${group.id}|}" th:text="#{generic.view}"></a>
+                        <button type="button" class="button delete" th:text="#{generic.remove}"
+                                th:onclick="|toggleOverlay('remove-submit-overlay-${group.id}')|"></button>
+                        <div th:id="|remove-submit-overlay-${group.id}|" class="overlay fit-to-content">
+                            <div class="boxed-group submit-form">
+                                <form th:action="@{|/group/remove/${group.id}|}" method="post">
+                                    <h1>Are you sure</h1>
+                                    <div class="form-buttons">
+                                        <button class="button delete" type="submit" th:text="#{generic.remove}"></button>
+                                        <button class="button" type="button" th:text="#{generic.cancel}"
+                                                th:onclick="|toggleOverlay('remove-submit-overlay-${group.id}')|"></button>
+                                    </div>
+                                </form>
+                            </div>
+                        </div>
+                    </div>
                 </div>
 
                 <div th:if="${staff}" th:id="|${group.id}-note-overlay|" class="overlay">
diff --git a/src/test/java/nl/tudelft/submit/controller/ModuleControllerTest.java b/src/test/java/nl/tudelft/submit/controller/ModuleControllerTest.java
index c675e3e77b21f701e4b759f34a61aabf4c151cc8..ac83a5a8713d92eb2d2985a968852d66fa6896c2 100644
--- a/src/test/java/nl/tudelft/submit/controller/ModuleControllerTest.java
+++ b/src/test/java/nl/tudelft/submit/controller/ModuleControllerTest.java
@@ -41,11 +41,7 @@ import nl.tudelft.submit.dto.view.statistics.ModuleStatisticsDTO;
 import nl.tudelft.submit.enums.DivisionsCreateType;
 import nl.tudelft.submit.enums.GradableType;
 import nl.tudelft.submit.security.AuthorizationService;
-import nl.tudelft.submit.service.EditionService;
-import nl.tudelft.submit.service.FormulaService;
-import nl.tudelft.submit.service.ModuleService;
-import nl.tudelft.submit.service.StatisticsService;
-import nl.tudelft.submit.service.StudentGroupService;
+import nl.tudelft.submit.service.*;
 
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -108,6 +104,9 @@ class ModuleControllerTest {
 	@MockBean
 	private EditionService editionService;
 
+	@MockBean
+	private ModuleDivisionService divisionService;
+
 	@MockBean
 	private AuthorizationService authService;
 
@@ -181,7 +180,7 @@ class ModuleControllerTest {
 				.andExpect(model().attribute("staff", false));
 
 		verify(authService).hasRoleInModule(MODULE_ID);
-		verify(groupService).showAllGroupsInModule(MODULE_ID, false);
+		verify(groupService).getAllGroupsInModule(MODULE_ID);
 	}
 
 	@Test
@@ -191,6 +190,7 @@ class ModuleControllerTest {
 		when(authService.hasStaffRoleInModule(anyLong())).thenReturn(false);
 		when(groupService.getGroupForPersonInModule(anyLong(), anyLong()))
 				.thenReturn(Optional.of(new StudentGroupDetailsDTO().id(GROUP_ID)));
+		when(moduleService.getModuleById(anyLong())).thenReturn(MODULE_VIEW);
 
 		mockMvc.perform(get("/module/{id}/groups", MODULE_ID))
 				.andExpect(status().is3xxRedirection())