From 970a6e3234ab70636b1120a474f79e9f36ae7d7f Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Mon, 30 Jul 2012 17:49:01 +0200
Subject: [PATCH] OO-291: customize every segment of the groups overview "My
 groups". Open the group tab after creating one.

---
 .../group/_spring/businessGroupContext.xml    |   2 +-
 .../AbstractBusinessGroupListController.java  |   8 +-
 .../ui/main/BusinessGroupListController.java  | 125 +-----------------
 .../FavoritBusinessGroupListController.java   |  76 +++++++++++
 .../OverviewBusinessGroupListController.java  | 114 ++++++++++++++++
 .../OwnedBusinessGroupListController.java     |  80 +++++++++++
 .../SearchBusinessGroupListController.java    | 123 +++++++++++++++++
 .../group/ui/main/_content/group_list.html    |   9 --
 .../ui/main/_content/group_list_overview.html |   7 +
 .../ui/main/_content/group_list_search.html   |  10 ++
 10 files changed, 419 insertions(+), 135 deletions(-)
 create mode 100644 src/main/java/org/olat/group/ui/main/FavoritBusinessGroupListController.java
 create mode 100644 src/main/java/org/olat/group/ui/main/OverviewBusinessGroupListController.java
 create mode 100644 src/main/java/org/olat/group/ui/main/OwnedBusinessGroupListController.java
 create mode 100644 src/main/java/org/olat/group/ui/main/SearchBusinessGroupListController.java
 create mode 100644 src/main/java/org/olat/group/ui/main/_content/group_list_overview.html
 create mode 100644 src/main/java/org/olat/group/ui/main/_content/group_list_search.html

diff --git a/src/main/java/org/olat/group/_spring/businessGroupContext.xml b/src/main/java/org/olat/group/_spring/businessGroupContext.xml
index e8a8d35f334..f8526317216 100644
--- a/src/main/java/org/olat/group/_spring/businessGroupContext.xml
+++ b/src/main/java/org/olat/group/_spring/businessGroupContext.xml
@@ -64,7 +64,7 @@
 		<property name="navigationKey" value="MyGroups" />
 		<property name="actionController">	
 			<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
-				<property name="className" value="org.olat.group.ui.main.BusinessGroupListController"/>
+				<property name="className" value="org.olat.group.ui.main.OverviewBusinessGroupListController"/>
 			</bean>
 		</property>
 		<property name="translationPackage" value="org.olat.group.ui.main" />
diff --git a/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java
index 1397f4d4365..21116d280d6 100644
--- a/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java
+++ b/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java
@@ -281,14 +281,20 @@ abstract class AbstractBusinessGroupListController extends BasicController {
 				doLeave(ureq, (BusinessGroup)leaveDialogBox.getUserObject());
 			}
 		} else if (source == groupCreateController) {
+			BusinessGroup group = null;
 			if(event == Event.DONE_EVENT) {
-				BusinessGroup group = groupCreateController.getCreatedGroup();
+				group = groupCreateController.getCreatedGroup();
 				if(group != null) {
 					reload();
 				}
 			}
 			cmc.deactivate();
 			cleanUpPopups();
+			//if new group -> go to the tab
+			if(group != null) {
+				String businessPath = "[BusinessGroup:" + group.getKey() + "]";
+				NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl());
+			}
 		} else if (source == businessGroupWizard) { 
 			if(event == Event.CANCELLED_EVENT || event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
 				getWindowControl().pop();
diff --git a/src/main/java/org/olat/group/ui/main/BusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/BusinessGroupListController.java
index 15fc0a807e1..fc17fa7ef2b 100644
--- a/src/main/java/org/olat/group/ui/main/BusinessGroupListController.java
+++ b/src/main/java/org/olat/group/ui/main/BusinessGroupListController.java
@@ -20,19 +20,11 @@
 package org.olat.group.ui.main;
 
 import org.olat.core.gui.UserRequest;
-import org.olat.core.gui.components.Component;
-import org.olat.core.gui.components.link.Link;
-import org.olat.core.gui.components.link.LinkFactory;
-import org.olat.core.gui.components.segmentedview.SegmentViewComponent;
-import org.olat.core.gui.components.segmentedview.SegmentViewEvent;
-import org.olat.core.gui.components.segmentedview.SegmentViewFactory;
 import org.olat.core.gui.components.table.BooleanColumnDescriptor;
 import org.olat.core.gui.components.table.ColumnDescriptor;
 import org.olat.core.gui.components.table.CustomCellRenderer;
 import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
 import org.olat.core.gui.components.table.DefaultColumnDescriptor;
-import org.olat.core.gui.control.Controller;
-import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.group.model.SearchBusinessGroupParams;
 import org.olat.group.ui.main.BusinessGroupTableModelWithType.Cols;
@@ -43,48 +35,13 @@ import org.olat.group.ui.main.BusinessGroupTableModelWithType.Cols;
  */
 public class BusinessGroupListController extends AbstractBusinessGroupListController {
 	
-	private final Link markedGroupsLink, allGroupsLink, ownedGroupsLink, searchOpenLink;
-	private final SegmentViewComponent segmentView;
-	private final BusinessGroupSearchController searchController;
-	
 	public BusinessGroupListController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl, "group_list");
-
-		//search controller
-		searchController = new BusinessGroupSearchController(ureq, wControl, isAdmin(), true);
-		listenTo(searchController);
-		mainVC.put("search", searchController.getInitialComponent());
-		searchController.getInitialComponent().setVisible(false);
-		mainVC.put("searchPanel", searchController.getInitialComponent());
-
-		//try to fill the table with marked groups	
-		boolean marked = updateMarkedGroups();
-		if(!marked) {
-			updateAllGroups();
-		}
-
-		//segmented view
-		segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
-		markedGroupsLink = LinkFactory.createLink("marked.groups", mainVC, this);
-		segmentView.addSegment(markedGroupsLink, marked);
-		allGroupsLink = LinkFactory.createLink("opengroups.all", mainVC, this);
-		segmentView.addSegment(allGroupsLink, !marked);
-		ownedGroupsLink = LinkFactory.createLink("owned.groups", mainVC, this);
-		segmentView.addSegment(ownedGroupsLink, false);
-		searchOpenLink = LinkFactory.createLink("opengroups.search", mainVC, this);
-		segmentView.addSegment(searchOpenLink, false);
 	}
 
 	@Override
 	protected void initButtons(UserRequest ureq) {
 		initButtons(ureq, true);
-		groupListCtr.setMultiSelect(true);
-		groupListCtr.addMultiSelectAction("table.duplicate", TABLE_ACTION_DUPLICATE);
-		groupListCtr.addMultiSelectAction("table.merge", TABLE_ACTION_MERGE);
-		groupListCtr.addMultiSelectAction("table.users.management", TABLE_ACTION_USERS);
-		groupListCtr.addMultiSelectAction("table.config", TABLE_ACTION_CONFIG);
-		groupListCtr.addMultiSelectAction("table.email", TABLE_ACTION_EMAIL);
-		groupListCtr.addMultiSelectAction("table.delete", TABLE_ACTION_DELETE);
 	}
 
 	@Override
@@ -106,55 +63,8 @@ public class BusinessGroupListController extends AbstractBusinessGroupListContro
 		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.accessControlLaunch.i18n(), Cols.accessControlLaunch.ordinal(), TABLE_ACTION_ACCESS, getLocale()));
 		return 7;
 	}
-
-	@Override
-	protected void doDispose() {
-		//
-	}
-	
-	@Override
-	protected void event(UserRequest ureq, Component source, Event event) {
-		if(source == segmentView) {
-			if(event instanceof SegmentViewEvent) {
-				SegmentViewEvent sve = (SegmentViewEvent)event;
-				String segmentCName = sve.getComponentName();
-				Component clickedLink = mainVC.getComponent(segmentCName);
-				if (clickedLink ==markedGroupsLink) {
-					updateMarkedGroups();
-				} else if (clickedLink == allGroupsLink){
-					updateAllGroups();
-				} else if (clickedLink == ownedGroupsLink){
-					updateOwnedGroups();
-				} else if (clickedLink == searchOpenLink) {
-					doSearch(null);
-				}
-				searchController.getInitialComponent().setVisible(clickedLink == searchOpenLink);
-			}
-		}
-		super.event(ureq, source, event);
-	}
-
-	@Override
-	protected void event(UserRequest ureq, Controller source, Event event) {
-		if(source == searchController) {
-			if(event instanceof SearchEvent) {
-				doSearch((SearchEvent)event);
-			}
-		}
-		super.event(ureq, source, event);
-	}
 	
-	private boolean updateMarkedGroups() {
-		SearchBusinessGroupParams params = new SearchBusinessGroupParams();
-		params.setMarked(Boolean.TRUE);
-		params.setAttendee(true);
-		params.setOwner(true);
-		params.setWaiting(true);
-		params.setIdentity(getIdentity());
-		return !updateTableModel(params, true).isEmpty();
-	}
-	
-	private void updateAllGroups() {
+	protected void updateAllGroups() {
 		SearchBusinessGroupParams params = new SearchBusinessGroupParams();
 		params.setAttendee(true);
 		params.setOwner(true);
@@ -162,37 +72,4 @@ public class BusinessGroupListController extends AbstractBusinessGroupListContro
 		params.setIdentity(getIdentity());
 		updateTableModel(params, false);
 	}
-	
-	private void updateOwnedGroups() {
-		SearchBusinessGroupParams params = new SearchBusinessGroupParams();
-		params.setIdentity(getIdentity());
-		params.setOwner(true);
-		updateTableModel(params, false);
-	}
-
-	private void doSearch(SearchEvent event) {
-		long start = isLogDebugEnabled() ? System.currentTimeMillis() : 0;
-
-		search(event);
-		
-		if(isLogDebugEnabled()) {
-			logDebug("Group search takes (ms): " + (System.currentTimeMillis() - start), null);
-		}
-	}
-
-	private void search(SearchEvent event) {
-		if(event == null) {
-			updateTableModel(null, false);
-		} else {
-			SearchBusinessGroupParams params = event.convertToSearchBusinessGroupParams(getIdentity());
-			//security
-			if(!params.isAttendee() && !params.isOwner() && !params.isWaiting()
-					&& (params.getPublicGroups() == null || !params.getPublicGroups().booleanValue())) {
-				params.setOwner(true);
-				params.setAttendee(true);
-				params.setWaiting(true);
-			}
-			updateTableModel(params, false);
-		}
-	}
 }
diff --git a/src/main/java/org/olat/group/ui/main/FavoritBusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/FavoritBusinessGroupListController.java
new file mode 100644
index 00000000000..43463ff7742
--- /dev/null
+++ b/src/main/java/org/olat/group/ui/main/FavoritBusinessGroupListController.java
@@ -0,0 +1,76 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.group.ui.main;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.table.BooleanColumnDescriptor;
+import org.olat.core.gui.components.table.ColumnDescriptor;
+import org.olat.core.gui.components.table.CustomCellRenderer;
+import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
+import org.olat.core.gui.components.table.DefaultColumnDescriptor;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.group.model.SearchBusinessGroupParams;
+import org.olat.group.ui.main.BusinessGroupTableModelWithType.Cols;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ */
+public class FavoritBusinessGroupListController extends AbstractBusinessGroupListController {
+
+	public FavoritBusinessGroupListController(UserRequest ureq, WindowControl wControl) {
+		super(ureq, wControl, "group_list");
+	}
+
+	@Override
+	protected void initButtons(UserRequest ureq) {
+		initButtons(ureq, true);
+	}
+
+	@Override
+	protected int initColumns() {
+		CustomCellRenderer markRenderer = new BGMarkCellRenderer(this, mainVC, getTranslator());
+		groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.mark.i18n(), Cols.resources.ordinal(), null, getLocale(),  ColumnDescriptor.ALIGNMENT_LEFT, markRenderer));
+		CustomCellRenderer acRenderer = new BGAccessControlledCellRenderer();
+		groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.accessTypes.i18n(), Cols.accessTypes.ordinal(), null, getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, acRenderer));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.name.i18n(), Cols.name.ordinal(), TABLE_ACTION_LAUNCH, getLocale()));
+		groupListCtr.addColumnDescriptor(false, new DefaultColumnDescriptor(Cols.description.i18n(), Cols.description.ordinal(), null, getLocale()));
+		CustomCellRenderer resourcesRenderer = new BGResourcesCellRenderer(this, mainVC, getTranslator());
+		groupListCtr.addColumnDescriptor(false, new CustomRenderColumnDescriptor(Cols.resources.i18n(), Cols.resources.ordinal(), null, getLocale(),  ColumnDescriptor.ALIGNMENT_LEFT, resourcesRenderer));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.firstTime.i18n(), Cols.firstTime.ordinal(), null, getLocale()));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.lastTime.i18n(), Cols.lastTime.ordinal(), null, getLocale()));
+		groupListCtr.addColumnDescriptor(false, new DefaultColumnDescriptor(Cols.lastUsage.i18n(), Cols.lastUsage.ordinal(), null, getLocale()));
+		CustomCellRenderer roleRenderer = new BGRoleCellRenderer(getLocale());
+		groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.role.i18n(), Cols.role.ordinal(), null, getLocale(),  ColumnDescriptor.ALIGNMENT_LEFT, roleRenderer));
+		groupListCtr.addColumnDescriptor(false, new BooleanColumnDescriptor(Cols.allowLeave.i18n(), Cols.allowLeave.ordinal(), TABLE_ACTION_LEAVE, translate("table.header.leave"), null));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.accessControlLaunch.i18n(), Cols.accessControlLaunch.ordinal(), TABLE_ACTION_ACCESS, getLocale()));
+		return 7;
+	}
+	
+	protected boolean updateMarkedGroups() {
+		SearchBusinessGroupParams params = new SearchBusinessGroupParams();
+		params.setMarked(Boolean.TRUE);
+		params.setAttendee(true);
+		params.setOwner(true);
+		params.setWaiting(true);
+		params.setIdentity(getIdentity());
+		return !updateTableModel(params, true).isEmpty();
+	}
+}
diff --git a/src/main/java/org/olat/group/ui/main/OverviewBusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/OverviewBusinessGroupListController.java
new file mode 100644
index 00000000000..ef920f2969c
--- /dev/null
+++ b/src/main/java/org/olat/group/ui/main/OverviewBusinessGroupListController.java
@@ -0,0 +1,114 @@
+package org.olat.group.ui.main;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.link.Link;
+import org.olat.core.gui.components.link.LinkFactory;
+import org.olat.core.gui.components.segmentedview.SegmentViewComponent;
+import org.olat.core.gui.components.segmentedview.SegmentViewEvent;
+import org.olat.core.gui.components.segmentedview.SegmentViewFactory;
+import org.olat.core.gui.components.velocity.VelocityContainer;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.controller.BasicController;
+
+/**
+ * 
+ * 
+ * 
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ */
+public class OverviewBusinessGroupListController extends BasicController {
+	
+	private final Link markedGroupsLink, allGroupsLink, ownedGroupsLink, searchOpenLink;
+	private final SegmentViewComponent segmentView;
+	private final VelocityContainer mainVC;
+
+	private FavoritBusinessGroupListController favoritGroupsCtrl;
+	private BusinessGroupListController allGroupsCtrl;
+	private OwnedBusinessGroupListController ownedGroupsCtrl;
+	private SearchBusinessGroupListController searchGroupsCtrl;
+	
+	public OverviewBusinessGroupListController(UserRequest ureq, WindowControl wControl) {
+		super(ureq, wControl);
+		
+		mainVC = createVelocityContainer("group_list_overview");
+		
+		boolean marked = updateMarkedGroups(ureq);
+		if(!marked) {
+			updateAllGroups(ureq);
+		}
+		
+		//segmented view
+		segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
+		markedGroupsLink = LinkFactory.createLink("marked.groups", mainVC, this);
+		segmentView.addSegment(markedGroupsLink, marked);
+		allGroupsLink = LinkFactory.createLink("opengroups.all", mainVC, this);
+		segmentView.addSegment(allGroupsLink, !marked);
+		ownedGroupsLink = LinkFactory.createLink("owned.groups", mainVC, this);
+		segmentView.addSegment(ownedGroupsLink, false);
+		searchOpenLink = LinkFactory.createLink("opengroups.search", mainVC, this);
+		segmentView.addSegment(searchOpenLink, false);
+		
+		putInitialPanel(mainVC);
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Component source, Event event) {
+		if(source == segmentView) {
+			if(event instanceof SegmentViewEvent) {
+				SegmentViewEvent sve = (SegmentViewEvent)event;
+				String segmentCName = sve.getComponentName();
+				Component clickedLink = mainVC.getComponent(segmentCName);
+				if (clickedLink == markedGroupsLink) {
+					updateMarkedGroups(ureq);
+				} else if (clickedLink == allGroupsLink){
+					updateAllGroups(ureq);
+				} else if (clickedLink == ownedGroupsLink){
+					updateOwnedGroups(ureq);
+				} else if (clickedLink == searchOpenLink) {
+					doSearch(ureq, null);
+				}
+			}
+		}
+	}
+
+	@Override
+	protected void doDispose() {
+		//
+	}
+	
+	private boolean updateMarkedGroups(UserRequest ureq) {
+		if(favoritGroupsCtrl == null) {
+			favoritGroupsCtrl = new FavoritBusinessGroupListController(ureq, getWindowControl());
+		}
+		boolean hasMark = favoritGroupsCtrl.updateMarkedGroups();
+		mainVC.put("groupList", favoritGroupsCtrl.getInitialComponent());
+		return hasMark;
+	}
+	
+	private void updateAllGroups(UserRequest ureq) {
+		if(allGroupsCtrl == null) {
+			allGroupsCtrl = new BusinessGroupListController(ureq, getWindowControl());
+		}
+		allGroupsCtrl.updateAllGroups();
+		mainVC.put("groupList", allGroupsCtrl.getInitialComponent());
+	}
+	
+	private void updateOwnedGroups(UserRequest ureq) {
+		if(ownedGroupsCtrl == null) {
+			ownedGroupsCtrl = new OwnedBusinessGroupListController(ureq, getWindowControl());
+		}
+		ownedGroupsCtrl.updateOwnedGroups();
+		mainVC.put("groupList", ownedGroupsCtrl.getInitialComponent());
+	}
+	
+	private void doSearch(UserRequest ureq, Object obj) {
+		if(searchGroupsCtrl == null) {
+			searchGroupsCtrl = new SearchBusinessGroupListController(ureq, getWindowControl());
+		}
+		searchGroupsCtrl.updateSearch();
+		mainVC.put("groupList", searchGroupsCtrl.getInitialComponent());
+	}
+}
diff --git a/src/main/java/org/olat/group/ui/main/OwnedBusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/OwnedBusinessGroupListController.java
new file mode 100644
index 00000000000..d99be17211f
--- /dev/null
+++ b/src/main/java/org/olat/group/ui/main/OwnedBusinessGroupListController.java
@@ -0,0 +1,80 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.group.ui.main;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.table.BooleanColumnDescriptor;
+import org.olat.core.gui.components.table.ColumnDescriptor;
+import org.olat.core.gui.components.table.CustomCellRenderer;
+import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
+import org.olat.core.gui.components.table.DefaultColumnDescriptor;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.group.model.SearchBusinessGroupParams;
+import org.olat.group.ui.main.BusinessGroupTableModelWithType.Cols;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ */
+public class OwnedBusinessGroupListController extends AbstractBusinessGroupListController {
+	
+	public OwnedBusinessGroupListController(UserRequest ureq, WindowControl wControl) {
+		super(ureq, wControl, "group_list");
+	}
+
+	@Override
+	protected void initButtons(UserRequest ureq) {
+		initButtons(ureq, true);
+		groupListCtr.setMultiSelect(true);
+		groupListCtr.addMultiSelectAction("table.duplicate", TABLE_ACTION_DUPLICATE);
+		groupListCtr.addMultiSelectAction("table.merge", TABLE_ACTION_MERGE);
+		groupListCtr.addMultiSelectAction("table.users.management", TABLE_ACTION_USERS);
+		groupListCtr.addMultiSelectAction("table.config", TABLE_ACTION_CONFIG);
+		groupListCtr.addMultiSelectAction("table.email", TABLE_ACTION_EMAIL);
+		groupListCtr.addMultiSelectAction("table.delete", TABLE_ACTION_DELETE);
+	}
+
+	@Override
+	protected int initColumns() {
+		CustomCellRenderer markRenderer = new BGMarkCellRenderer(this, mainVC, getTranslator());
+		groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.mark.i18n(), Cols.resources.ordinal(), null, getLocale(),  ColumnDescriptor.ALIGNMENT_LEFT, markRenderer));
+		CustomCellRenderer acRenderer = new BGAccessControlledCellRenderer();
+		groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.accessTypes.i18n(), Cols.accessTypes.ordinal(), null, getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, acRenderer));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.name.i18n(), Cols.name.ordinal(), TABLE_ACTION_LAUNCH, getLocale()));
+		groupListCtr.addColumnDescriptor(false, new DefaultColumnDescriptor(Cols.description.i18n(), Cols.description.ordinal(), null, getLocale()));
+		CustomCellRenderer resourcesRenderer = new BGResourcesCellRenderer(this, mainVC, getTranslator());
+		groupListCtr.addColumnDescriptor(false, new CustomRenderColumnDescriptor(Cols.resources.i18n(), Cols.resources.ordinal(), null, getLocale(),  ColumnDescriptor.ALIGNMENT_LEFT, resourcesRenderer));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.firstTime.i18n(), Cols.firstTime.ordinal(), null, getLocale()));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.lastTime.i18n(), Cols.lastTime.ordinal(), null, getLocale()));
+		groupListCtr.addColumnDescriptor(false, new DefaultColumnDescriptor(Cols.lastUsage.i18n(), Cols.lastUsage.ordinal(), null, getLocale()));
+		CustomCellRenderer roleRenderer = new BGRoleCellRenderer(getLocale());
+		groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.role.i18n(), Cols.role.ordinal(), null, getLocale(),  ColumnDescriptor.ALIGNMENT_LEFT, roleRenderer));
+		groupListCtr.addColumnDescriptor(false, new BooleanColumnDescriptor(Cols.allowLeave.i18n(), Cols.allowLeave.ordinal(), TABLE_ACTION_LEAVE, translate("table.header.leave"), null));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.accessControlLaunch.i18n(), Cols.accessControlLaunch.ordinal(), TABLE_ACTION_ACCESS, getLocale()));
+		return 7;
+	}
+	
+	protected void updateOwnedGroups() {
+		SearchBusinessGroupParams params = new SearchBusinessGroupParams();
+		params.setIdentity(getIdentity());
+		params.setOwner(true);
+		updateTableModel(params, false);
+	}
+}
diff --git a/src/main/java/org/olat/group/ui/main/SearchBusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/SearchBusinessGroupListController.java
new file mode 100644
index 00000000000..f1e4fb28098
--- /dev/null
+++ b/src/main/java/org/olat/group/ui/main/SearchBusinessGroupListController.java
@@ -0,0 +1,123 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.group.ui.main;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.table.BooleanColumnDescriptor;
+import org.olat.core.gui.components.table.ColumnDescriptor;
+import org.olat.core.gui.components.table.CustomCellRenderer;
+import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
+import org.olat.core.gui.components.table.DefaultColumnDescriptor;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.group.model.SearchBusinessGroupParams;
+import org.olat.group.ui.main.BusinessGroupTableModelWithType.Cols;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ */
+public class SearchBusinessGroupListController extends AbstractBusinessGroupListController {
+	
+
+	private final BusinessGroupSearchController searchController;
+	
+	public SearchBusinessGroupListController(UserRequest ureq, WindowControl wControl) {
+		super(ureq, wControl, "group_list_search");
+
+		//search controller
+		searchController = new BusinessGroupSearchController(ureq, wControl, isAdmin(), true);
+		listenTo(searchController);
+		mainVC.put("search", searchController.getInitialComponent());
+	}
+
+	@Override
+	protected void initButtons(UserRequest ureq) {
+		initButtons(ureq, true);
+		groupListCtr.setMultiSelect(true);
+		groupListCtr.addMultiSelectAction("table.duplicate", TABLE_ACTION_DUPLICATE);
+		groupListCtr.addMultiSelectAction("table.merge", TABLE_ACTION_MERGE);
+		groupListCtr.addMultiSelectAction("table.users.management", TABLE_ACTION_USERS);
+		groupListCtr.addMultiSelectAction("table.config", TABLE_ACTION_CONFIG);
+		groupListCtr.addMultiSelectAction("table.email", TABLE_ACTION_EMAIL);
+		groupListCtr.addMultiSelectAction("table.delete", TABLE_ACTION_DELETE);
+	}
+
+	@Override
+	protected int initColumns() {
+		CustomCellRenderer markRenderer = new BGMarkCellRenderer(this, mainVC, getTranslator());
+		groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.mark.i18n(), Cols.resources.ordinal(), null, getLocale(),  ColumnDescriptor.ALIGNMENT_LEFT, markRenderer));
+		CustomCellRenderer acRenderer = new BGAccessControlledCellRenderer();
+		groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.accessTypes.i18n(), Cols.accessTypes.ordinal(), null, getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, acRenderer));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.name.i18n(), Cols.name.ordinal(), TABLE_ACTION_LAUNCH, getLocale()));
+		groupListCtr.addColumnDescriptor(false, new DefaultColumnDescriptor(Cols.description.i18n(), Cols.description.ordinal(), null, getLocale()));
+		CustomCellRenderer resourcesRenderer = new BGResourcesCellRenderer(this, mainVC, getTranslator());
+		groupListCtr.addColumnDescriptor(false, new CustomRenderColumnDescriptor(Cols.resources.i18n(), Cols.resources.ordinal(), null, getLocale(),  ColumnDescriptor.ALIGNMENT_LEFT, resourcesRenderer));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.firstTime.i18n(), Cols.firstTime.ordinal(), null, getLocale()));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.lastTime.i18n(), Cols.lastTime.ordinal(), null, getLocale()));
+		groupListCtr.addColumnDescriptor(false, new DefaultColumnDescriptor(Cols.lastUsage.i18n(), Cols.lastUsage.ordinal(), null, getLocale()));
+		CustomCellRenderer roleRenderer = new BGRoleCellRenderer(getLocale());
+		groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.role.i18n(), Cols.role.ordinal(), null, getLocale(),  ColumnDescriptor.ALIGNMENT_LEFT, roleRenderer));
+		groupListCtr.addColumnDescriptor(false, new BooleanColumnDescriptor(Cols.allowLeave.i18n(), Cols.allowLeave.ordinal(), TABLE_ACTION_LEAVE, translate("table.header.leave"), null));
+		groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor(Cols.accessControlLaunch.i18n(), Cols.accessControlLaunch.ordinal(), TABLE_ACTION_ACCESS, getLocale()));
+		return 7;
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Controller source, Event event) {
+		if(source == searchController) {
+			if(event instanceof SearchEvent) {
+				doSearch((SearchEvent)event);
+			}
+		}
+		super.event(ureq, source, event);
+	}
+	
+	protected void updateSearch() {
+		doSearch(null);
+	}
+
+	private void doSearch(SearchEvent event) {
+		long start = isLogDebugEnabled() ? System.currentTimeMillis() : 0;
+
+		search(event);
+		
+		if(isLogDebugEnabled()) {
+			logDebug("Group search takes (ms): " + (System.currentTimeMillis() - start), null);
+		}
+	}
+
+	private void search(SearchEvent event) {
+		if(event == null) {
+			updateTableModel(null, false);
+		} else {
+			SearchBusinessGroupParams params = event.convertToSearchBusinessGroupParams(getIdentity());
+			//security
+			if(!params.isAttendee() && !params.isOwner() && !params.isWaiting()
+					&& (params.getPublicGroups() == null || !params.getPublicGroups().booleanValue())) {
+				params.setOwner(true);
+				params.setAttendee(true);
+				params.setWaiting(true);
+			}
+			updateTableModel(params, false);
+		}
+	}
+}
diff --git a/src/main/java/org/olat/group/ui/main/_content/group_list.html b/src/main/java/org/olat/group/ui/main/_content/group_list.html
index 1eae7c64f02..d69ce5bc03e 100644
--- a/src/main/java/org/olat/group/ui/main/_content/group_list.html
+++ b/src/main/java/org/olat/group/ui/main/_content/group_list.html
@@ -1,13 +1,4 @@
-<h4 class="b_with_small_icon_left b_group_icon">
-	$r.translate("menu.groups")
-</h4>
 <div class="b_clearfix">
-	$r.render("segments") <br/>	
-	
-	#if($r.available("search"))
-		$r.render("search")
-	#end
-	
 	$r.render("groupList")
 </div>
 #if($r.available("create.group"))
diff --git a/src/main/java/org/olat/group/ui/main/_content/group_list_overview.html b/src/main/java/org/olat/group/ui/main/_content/group_list_overview.html
new file mode 100644
index 00000000000..79d6e4e122b
--- /dev/null
+++ b/src/main/java/org/olat/group/ui/main/_content/group_list_overview.html
@@ -0,0 +1,7 @@
+<h4 class="b_with_small_icon_left b_group_icon">
+	$r.translate("menu.groups")
+</h4>
+<div class="b_clearfix">
+	$r.render("segments")<br/>
+	$r.render("groupList")
+</div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/group/ui/main/_content/group_list_search.html b/src/main/java/org/olat/group/ui/main/_content/group_list_search.html
new file mode 100644
index 00000000000..359934fd30a
--- /dev/null
+++ b/src/main/java/org/olat/group/ui/main/_content/group_list_search.html
@@ -0,0 +1,10 @@
+<div class="b_clearfix">
+	$r.render("search")
+	$r.render("groupList")
+</div>
+#if($r.available("create.group"))
+	<div class="b_clearfix">
+		<p>$r.translate("create.group.description")</p>
+		$r.render("create.group")
+	</div>
+#end
\ No newline at end of file
-- 
GitLab