Skip to content
Snippets Groups Projects
Commit 93efa541 authored by srosse's avatar srosse
Browse files

OO-1000: port back coaching tool

parent 09ea9aa4
No related branches found
No related tags found
No related merge requests found
Showing
with 2493 additions and 4 deletions
...@@ -45,8 +45,12 @@ ...@@ -45,8 +45,12 @@
<property name="order" value="6" /> <property name="order" value="6" />
<property name="enabled" value="${site.repository.enable}"/> <property name="enabled" value="${site.repository.enable}"/>
</bean> </bean>
<bean id="olatsites_coaching" class="org.olat.modules.coach.site.CoachSiteDef">
<property name="order" value="7" />
<property name="enabled" value="${site.coaching.enable}"/>
</bean>
<bean id="olatsites_qpool" class="org.olat.modules.qpool.site.QuestionPoolSiteDef"> <bean id="olatsites_qpool" class="org.olat.modules.qpool.site.QuestionPoolSiteDef">
<property name="order" value="7" /> <property name="order" value="8" />
<property name="enabled" value="${site.questionpool.enable}"/> <property name="enabled" value="${site.questionpool.enable}"/>
</bean> </bean>
<bean id="olatsites_useradmin" class="org.olat.admin.site.UserAdminSiteDef"> <bean id="olatsites_useradmin" class="org.olat.admin.site.UserAdminSiteDef">
......
/**
* <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.modules.coach;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.olat.modules.coach.ui.CourseListController;
import org.olat.modules.coach.ui.GroupListController;
import org.olat.modules.coach.ui.StudentListController;
/**
*
* Description:<br>
* UI factory for the coach site (used by the controller creator configured
* in coachContext.xml)
*
* <P>
* Initial Date: 8 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CoachUIFactory {
/**
* Return a controller which shows an overview over all students the user tutored.
* tutoring.
* @param ureq
* @param wControl
* @return The students overview controller
*/
public static Controller createStudentsController(UserRequest ureq, WindowControl wControl) {
return new StudentListController(ureq, wControl);
}
/**
* Return a controller which shows an overview of all groups the user tutored.
* @param ureq
* @param wControl
* @return The groups overview controller
*/
public static Controller createGroupsController(UserRequest ureq, WindowControl wControl) {
return new GroupListController(ureq, wControl);
}
/**
* Return a controller which shows an overview of all courses the user tutored.
* @param ureq
* @param wControl
* @return The courses overview controller
*/
public static Controller createCoursesController(UserRequest ureq, WindowControl wControl) {
return new CourseListController(ureq, wControl);
}
}
/**
* <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.modules.coach;
import org.olat.NewControllerFactory;
import org.olat.core.configuration.AbstractOLATModule;
import org.olat.core.configuration.ConfigOnOff;
import org.olat.core.configuration.PersistedProperties;
import org.olat.core.util.StringHelper;
import org.olat.modules.coach.site.CoachContextEntryControllerCreator;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 8 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CoachingModule extends AbstractOLATModule implements ConfigOnOff {
private boolean enabled;
private CoachingModule() {
//
}
@Override
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
if(this.enabled != enabled) {
setStringProperty("coaching.enabled", Boolean.toString(enabled), true);
}
}
@Override
public void init() {
// Add controller factory extension point to launch groups
NewControllerFactory.getInstance().addContextEntryControllerCreator("coaching",
new CoachContextEntryControllerCreator());
//portfolio enabled/disabled
String enabledObj = getStringPropertyValue("coaching.enabled", true);
if(StringHelper.containsNonWhitespace(enabledObj)) {
enabled = "true".equals(enabledObj);
}
}
@Override
public void setPersistedProperties(PersistedProperties persistedProperties) {
this.moduleConfigProperties = persistedProperties;
}
@Override
protected void initDefaultProperties() {
enabled = getBooleanConfigParameter("coaching.enabled", true);
}
@Override
protected void initFromChangedProperties() {
init();
}
}
...@@ -3,11 +3,115 @@ ...@@ -3,11 +3,115 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.frentix.olat.coach" /> <context:component-scan base-package="org.olat.modules.coach" />
<bean id="coachingModule" class="org.olat.modules.coach.CoachingModule" init-method="init"
depends-on="">
<property name="persistedProperties">
<bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy">
<constructor-arg index="0" ref="coordinatorManager"/>
<constructor-arg index="1" ref="coachingModule" />
<constructor-arg index="2" value="com.frentix.olat.coach.CoachingModule" />
<constructor-arg index="3" value="false" />
</bean>
</property>
</bean>
<!-- default configuration -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="coachingModule" />
<property name="targetMethod" value="init" />
<property name="arguments">
<value>
coaching.enabled=${site.coaching.enable}
</value>
</property>
</bean>
<!-- the REST API menu-entry -->
<bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints">
<property name="order" value="7208" />
<property name="navigationKey" value="coachingAdmin" />
<property name="actionController">
<bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype">
<property name="className" value="org.olat.modules.coach.ui.CoachAdminController"/>
</bean>
</property>
<property name="i18nActionKey" value="menu.coaching"/>
<property name="i18nDescriptionKey" value="menu.coaching.alt"/>
<property name="translationPackage" value="org.olat.modules.coach.ui"/>
<property name="extensionPoints">
<list>
<value>org.olat.admin.SystemAdminMainController</value>
</list>
</property>
<property name="parentTreeNodeIdentifier" value="modulesParent" />
</bean>
<!-- students menu item -->
<bean class="org.olat.core.extensions.action.GenericActionExtension" id="coach.menupoint.student" init-method="initExtensionPoints" >
<property name="order" value="701" />
<property name="navigationKey" value="students" />
<property name="actionController">
<bean class=" org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype">
<property name="factoryName" value="org.olat.modules.coach.CoachUIFactory"/>
<property name="factoryMethod" value="createStudentsController"/>
</bean>
</property>
<property name="translationPackage" value="org.olat.modules.coach.ui" />
<property name="i18nActionKey" value="students.menu.title"/>
<property name="i18nDescriptionKey" value="students.menu.title.alt"/>
<property name="extensionPoints">
<list>
<value>org.olat.modules.coach.ui.CoachMainController</value>
</list>
</property>
</bean>
<!-- students menu item -->
<bean class="org.olat.core.extensions.action.GenericActionExtension" id="coach.menupoint.group" init-method="initExtensionPoints" >
<property name="order" value="702" />
<property name="navigationKey" value="groups" />
<property name="actionController">
<bean class=" org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype">
<property name="factoryName" value="org.olat.modules.coach.CoachUIFactory"/>
<property name="factoryMethod" value="createGroupsController"/>
</bean>
</property>
<property name="translationPackage" value="org.olat.modules.coach.ui" />
<property name="i18nActionKey" value="groups.menu.title"/>
<property name="i18nDescriptionKey" value="groups.menu.title.alt"/>
<property name="extensionPoints">
<list>
<value>org.olat.modules.coach.ui.CoachMainController</value>
</list>
</property>
</bean>
<!-- students menu item -->
<bean class="org.olat.core.extensions.action.GenericActionExtension" id="coach.menupoint.course" init-method="initExtensionPoints" >
<property name="order" value="703" />
<property name="navigationKey" value="courses" />
<property name="actionController">
<bean class=" org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype">
<property name="factoryName" value="org.olat.modules.coach.CoachUIFactory"/>
<property name="factoryMethod" value="createCoursesController"/>
</bean>
</property>
<property name="translationPackage" value="org.olat.modules.coach.ui" />
<property name="i18nActionKey" value="courses.menu.title"/>
<property name="i18nDescriptionKey" value="courses.menu.title.alt"/>
<property name="extensionPoints">
<list>
<value>org.olat.modules.coach.ui.CoachMainController</value>
</list>
</property>
</bean>
</beans> </beans>
\ No newline at end of file
/**
* <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.modules.coach.site;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.ContextEntryControllerCreator;
import org.olat.core.id.context.DefaultContextEntryControllerCreator;
/**
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CoachContextEntryControllerCreator extends DefaultContextEntryControllerCreator {
@Override
public ContextEntryControllerCreator clone() {
return this;
}
@Override
public String getSiteClassName(ContextEntry ce, UserRequest ureq) {
return CoachSite.class.getName();
}
@Override
public boolean validateContextEntryAndShowError(ContextEntry ce, UserRequest ureq, WindowControl wControl) {
return super.validateContextEntryAndShowError(ce, ureq, wControl);
}
}
/**
* <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.modules.coach.site;
import java.util.Locale;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.layout.MainLayoutController;
import org.olat.core.gui.control.navigation.AbstractSiteInstance;
import org.olat.core.gui.control.navigation.DefaultNavElement;
import org.olat.core.gui.control.navigation.NavElement;
import org.olat.core.gui.control.navigation.SiteConfiguration;
import org.olat.core.gui.control.navigation.SiteDefinition;
import org.olat.core.gui.translator.Translator;
import org.olat.core.id.OLATResourceable;
import org.olat.core.id.context.BusinessControlFactory;
import org.olat.core.id.context.StateSite;
import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
import org.olat.core.util.Util;
import org.olat.core.util.resource.OresHelper;
import org.olat.modules.coach.ui.CoachMainController;
import org.olat.util.logging.activity.LoggingResourceable;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 7 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CoachSite extends AbstractSiteInstance {
private final NavElement origNavElem;
private NavElement curNavElem;
/**
* @param loccale
*/
public CoachSite(SiteDefinition siteDef, Locale locale) {
super(siteDef);
Translator trans = Util.createPackageTranslator(CoachMainController.class, locale);
origNavElem = new DefaultNavElement(trans.translate("site.title"), trans.translate("site.title.alt"), "o_site_coaching");
curNavElem = new DefaultNavElement(origNavElem);
}
@Override
public NavElement getNavElement() {
return curNavElem;
}
@Override
protected MainLayoutController createController(UserRequest ureq, WindowControl wControl, SiteConfiguration config) {
OLATResourceable ores = OresHelper.createOLATResourceableInstance(CoachSite.class, 0l);
ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores));
WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, new StateSite(this), wControl, true);
CoachMainController mainController = new CoachMainController(ureq, bwControl);
return mainController;
}
@Override
public void reset() {
curNavElem = new DefaultNavElement(origNavElem);
}
}
/**
* <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.modules.coach.site;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.navigation.AbstractSiteDefinition;
import org.olat.core.gui.control.navigation.SiteConfiguration;
import org.olat.core.gui.control.navigation.SiteDefinition;
import org.olat.core.gui.control.navigation.SiteInstance;
import org.olat.modules.coach.CoachingModule;
import org.olat.modules.coach.CoachingService;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 7 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CoachSiteDef extends AbstractSiteDefinition implements SiteDefinition {
@Override
protected SiteInstance createSite(UserRequest ureq, WindowControl wControl, SiteConfiguration config) {
CoachingModule module = CoreSpringFactory.getImpl(CoachingModule.class);
if(module.isEnabled()) {
CoachingService coachingService = CoreSpringFactory.getImpl(CoachingService.class);
if(coachingService.isCoach(ureq.getIdentity())) {
return new CoachSite(this, ureq.getLocale());
}
}
return null;
}
}
/**
* <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.modules.coach.ui;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.olat.modules.coach.CoachingModule;
/**
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CoachAdminController extends FormBasicController {
private MultipleSelectionElement enabled;
private String[] values = {""};
private String[] keys = {"on"};
public CoachAdminController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl);
values = new String[] {
getTranslator().translate("coaching.on")
};
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
setFormTitle("coaching.title");
setFormContextHelp(CoachAdminController.class.getPackage().getName(), "coaching.html", "help.hover.coaching");
if(formLayout instanceof FormLayoutContainer) {
FormLayoutContainer layoutContainer = (FormLayoutContainer)formLayout;
boolean restEnabled = isEnabled();
enabled = uifactory.addCheckboxesHorizontal("coaching.enabled", formLayout, keys, values, null);
enabled.select(keys[0], restEnabled);
final FormLayoutContainer buttonGroupLayout = FormLayoutContainer.createButtonLayout("buttonLayout", getTranslator());
buttonGroupLayout.setRootForm(mainForm);
layoutContainer.add(buttonGroupLayout);
uifactory.addFormSubmitButton("save", buttonGroupLayout);
}
}
@Override
protected void doDispose() {
//
}
@Override
protected void formOK(UserRequest ureq) {
boolean on = !enabled.getSelectedKeys().isEmpty();
setEnabled(on);
getWindowControl().setInfo("saved");
}
private boolean isEnabled() {
CoachingModule config = CoreSpringFactory.getImpl(CoachingModule.class);
return config.isEnabled();
}
private void setEnabled(boolean enabled) {
CoachingModule config = CoreSpringFactory.getImpl(CoachingModule.class);
config.setEnabled(enabled);
}
}
/**
* <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.modules.coach.ui;
import java.util.List;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.dtabs.Activateable2;
import org.olat.core.gui.control.generic.layout.GenericMainController;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.StateEntry;
import org.olat.core.util.event.GenericEventListener;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 7 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CoachMainController extends GenericMainController implements GenericEventListener, Activateable2 {
public CoachMainController(UserRequest ureq, WindowControl control) {
super(ureq, control);
init(ureq);
addCssClassToMain("o_coaching");
getMenuTree().setRootVisible(false);
}
@Override
protected Controller handleOwnMenuTreeEvent(Object uobject, UserRequest ureq) {
return null;
}
@Override
public void event(Event event) {
//
}
@Override
public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
super.activate(ureq, entries, state);
}
}
\ No newline at end of file
/**
* <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.modules.coach.ui;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
/**
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class ContactController extends FormBasicController {
public ContactController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl);
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
setFormTitle("contact.title");
//
}
@Override
protected void doDispose() {
//
}
@Override
protected void formOK(UserRequest ureq) {
//
}
}
/**
* <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.modules.coach.ui;
import java.util.ArrayList;
import java.util.List;
import org.olat.NewControllerFactory;
import org.olat.core.CoreSpringFactory;
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.table.BooleanColumnDescriptor;
import org.olat.core.gui.components.table.ColumnDescriptor;
import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
import org.olat.core.gui.components.table.DefaultColumnDescriptor;
import org.olat.core.gui.components.table.TableController;
import org.olat.core.gui.components.table.TableDataModel;
import org.olat.core.gui.components.table.TableEvent;
import org.olat.core.gui.components.table.TableGuiConfiguration;
import org.olat.core.gui.components.text.TextComponent;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
import org.olat.core.gui.control.generic.dtabs.Activateable2;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.id.context.BusinessControl;
import org.olat.core.id.context.BusinessControlFactory;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.StateEntry;
import org.olat.core.util.StringHelper;
import org.olat.core.util.resource.OresHelper;
import org.olat.modules.coach.CoachingService;
import org.olat.modules.coach.model.CourseStatEntry;
import org.olat.modules.coach.model.EfficiencyStatementEntry;
import org.olat.repository.RepositoryEntry;
import org.olat.modules.coach.ui.EfficiencyStatementEntryTableDataModel.Columns;
import org.olat.modules.coach.ui.ToolbarController.Position;
/**
*
* Description:<br>
* Overview of all students under the scrutiny of a coach.
*
* <P>
* Initial Date: 8 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CourseController extends BasicController implements Activateable2 {
private final Link backLink, next, previous;
private final Link nextCourse, previousCourse;
private final Link openCourse;
private final TextComponent detailsCmp, detailsCourseCmp;
private final TableController tableCtr;
private final VelocityContainer mainVC;
private final VelocityContainer courseDetailsVC;
private CloseableModalController cmc;
private ContactController contactCtrl;
private final ToolbarController toolbar;
private EfficiencyStatementDetailsController statementCtrl;
private boolean hasChanged = false;
private final RepositoryEntry course;
private final CourseStatEntry courseStat;
private final CoachingService coachingService;
public CourseController(UserRequest ureq, WindowControl wControl, RepositoryEntry course, CourseStatEntry courseStat, int index, int numOfCourses) {
super(ureq, wControl);
this.course = course;
this.courseStat = courseStat;
coachingService = CoreSpringFactory.getImpl(CoachingService.class);
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setTableEmptyMessage(translate("error.no.found"));
tableConfig.setDownloadOffered(true);
tableConfig.setPreferencesOffered(true, "courseController");
tableCtr = new TableController(tableConfig, ureq, getWindowControl(), null, null, null, null, true, getTranslator());
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("student.name", Columns.studentName.ordinal(), "select", getLocale()));
tableCtr.addColumnDescriptor(false, new DefaultColumnDescriptor("table.header.course.name", Columns.repoName.ordinal(), "select", getLocale()));
tableCtr.addColumnDescriptor(new BooleanColumnDescriptor("table.header.passed", Columns.passed.ordinal(), translate("passed.true"), translate("passed.false")));
tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.score", Columns.score.ordinal(), "select", getLocale(),
ColumnDescriptor.ALIGNMENT_RIGHT, new ScoreCellRenderer()));
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.lastScoreDate", Columns.lastModification.ordinal(), "select", getLocale()));
listenTo(tableCtr);
List<EfficiencyStatementEntry> entries = loadModel();
mainVC = createVelocityContainer("course");
courseDetailsVC = createVelocityContainer("course_details");
courseDetailsVC.contextPut("courseName", StringHelper.escapeHtml(course.getDisplayname()));
toolbar = new ToolbarController(ureq, wControl, getTranslator());
listenTo(toolbar);
backLink = toolbar.addToolbarLink("back", this, Position.left);
backLink.setCustomEnabledLinkCSS("b_link_back");
previous = toolbar.addToolbarLink("previous", this, Position.center);
previous.setCustomEnabledLinkCSS("b_with_small_icon_left b_move_left_icon");
previous.setEnabled(entries.size() > 1);
detailsCmp = toolbar.addToolbarText("", this, Position.center);
next = toolbar.addToolbarLink("next", this, Position.center);
next.setCustomEnabledLinkCSS("b_with_small_icon_right b_move_right_icon");
next.setEnabled(entries.size() > 1);
//courses next,previous
previousCourse = toolbar.addToolbarLink("previous.course", this, Position.center);
previousCourse.setCustomEnabledLinkCSS("b_with_small_icon_left b_move_left_icon");
previousCourse.setEnabled(numOfCourses > 1);
detailsCourseCmp = toolbar.addToolbarText("details.course", "", this, Position.center);
detailsCourseCmp.setText(translate("students.details", new String[]{
StringHelper.escapeHtml(course.getDisplayname()),
Integer.toString(index + 1), Integer.toString(numOfCourses)
}));
nextCourse = toolbar.addToolbarLink("next.course", this, Position.center);
nextCourse.setCustomEnabledLinkCSS("b_with_small_icon_right b_move_right_icon");
nextCourse.setEnabled(numOfCourses > 1);
openCourse = LinkFactory.createButton("open", courseDetailsVC, this);
openCourse.setCustomEnabledLinkCSS("b_link_left_icon b_link_course");
courseDetailsVC.put("open", openCourse);
mainVC.put("toolbar", toolbar.getInitialComponent());
mainVC.put("courseTable", tableCtr.getInitialComponent());
mainVC.put("courseDetails", courseDetailsVC);
setDetailsToolbarVisible(false);
putInitialPanel(mainVC);
}
public CourseStatEntry getEntry() {
return courseStat;
}
public List<EfficiencyStatementEntry> loadModel() {
List<EfficiencyStatementEntry> entries = coachingService.getCourse(getIdentity(), course, 0, -1);
TableDataModel<EfficiencyStatementEntry> model = new EfficiencyStatementEntryTableDataModel(entries);
tableCtr.setTableDataModel(model);
return entries;
}
private void reloadModel() {
if(hasChanged) {
loadModel();
hasChanged = false;
}
}
@Override
protected void doDispose() {
//
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
if (source == next) {
nextEntry(ureq);
} else if (source == previous) {
previousEntry(ureq);
} else if (source == backLink) {
back(ureq);
} else if (source == openCourse) {
openCourse(ureq);
}
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(source == tableCtr) {
if(event instanceof TableEvent) {
TableEvent e = (TableEvent) event;
if("select".equals(e.getActionId())) {
EfficiencyStatementEntry entry = (EfficiencyStatementEntry)tableCtr.getTableDataModel().getObject(e.getRowId());
selectDetails(ureq, entry);
}
}
} else if (source == statementCtrl) {
if(event == Event.CHANGED_EVENT) {
hasChanged = true;
fireEvent(ureq, Event.CHANGED_EVENT);
} else {
removeDetails(ureq);
}
} else if (source == cmc) {
removeAsListenerAndDispose(cmc);
removeAsListenerAndDispose(contactCtrl);
cmc = null;
contactCtrl = null;
} else if (source == toolbar) {
if("back".equals(event.getCommand())) {
reloadModel();
back(ureq);
} else if("next".equals(event.getCommand())) {
nextEntry(ureq);
} else if("previous".equals(event.getCommand())) {
previousEntry(ureq);
} else if("contact.link".equals(event.getCommand())) {
contact(ureq);
} else if ("next.course".equals(event.getCommand())) {
fireEvent(ureq, event);
} else if ("previous.course".equals(event.getCommand())) {
fireEvent(ureq, event);
}
}
super.event(ureq, source, event);
}
@Override
public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
if(entries == null || entries.isEmpty()) return;
ContextEntry ce = entries.get(0);
OLATResourceable ores = ce.getOLATResourceable();
if("Identity".equals(ores.getResourceableTypeName())) {
Long identityKey = ores.getResourceableId();
for(int i=tableCtr.getRowCount(); i-->0; ) {
EfficiencyStatementEntry entry = (EfficiencyStatementEntry)tableCtr.getTableDataModel().getObject(i);
if(identityKey.equals(entry.getStudentKey())) {
selectDetails(ureq, entry);
statementCtrl.activate(ureq, entries.subList(1, entries.size()), ce.getTransientState());
break;
}
}
}
}
private void setDetailsToolbarVisible(boolean visible) {
next.setVisible(visible);
previous.setVisible(visible);
detailsCmp.setVisible(visible);
nextCourse.setVisible(!visible);
previousCourse.setVisible(!visible);
detailsCourseCmp.setVisible(!visible);
}
private void contact(UserRequest ureq) {
removeAsListenerAndDispose(cmc);
if(statementCtrl != null) {
contactCtrl = new ContactController(ureq, getWindowControl());
cmc = new CloseableModalController(getWindowControl(), translate("close"), contactCtrl.getInitialComponent());
cmc.activate();
listenTo(cmc);
}
}
private void back(UserRequest ureq) {
if(statementCtrl == null) {
fireEvent(ureq, Event.BACK_EVENT);
} else {
removeDetails(ureq);
}
}
private void previousEntry(UserRequest ureq) {
EfficiencyStatementEntry currentEntry = statementCtrl.getEntry();
int previousIndex = tableCtr.getIndexOfSortedObject(currentEntry) - 1;
if(previousIndex < 0 || previousIndex >= tableCtr.getRowCount()) {
previousIndex = tableCtr.getRowCount() - 1;
}
EfficiencyStatementEntry previousEntry = (EfficiencyStatementEntry)tableCtr.getSortedObjectAt(previousIndex);
selectDetails(ureq, previousEntry);
}
private void nextEntry(UserRequest ureq) {
EfficiencyStatementEntry currentEntry = statementCtrl.getEntry();
int nextIndex = tableCtr.getIndexOfSortedObject(currentEntry) + 1;
if(nextIndex < 0 || nextIndex >= tableCtr.getRowCount()) {
nextIndex = 0;
}
EfficiencyStatementEntry nextEntry = (EfficiencyStatementEntry)tableCtr.getSortedObjectAt(nextIndex);
selectDetails(ureq, nextEntry);
}
private void removeDetails(UserRequest ureq) {
mainVC.remove(statementCtrl.getInitialComponent());
removeAsListenerAndDispose(statementCtrl);
statementCtrl = null;
setDetailsToolbarVisible(false);
addToHistory(ureq);
}
private void selectDetails(UserRequest ureq, EfficiencyStatementEntry entry) {
removeAsListenerAndDispose(statementCtrl);
OLATResourceable ores = OresHelper.createOLATResourceableInstance(Identity.class, entry.getStudentKey());
WindowControl bwControl = addToHistory(ureq, ores, null);
statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry, null);
listenTo(statementCtrl);
mainVC.put("efficiencyDetails", statementCtrl.getInitialComponent());
int index = tableCtr.getIndexOfSortedObject(entry) + 1;
String details = translate("students.details", new String[] {
StringHelper.escapeHtml(entry.getStudentFullName()),
String.valueOf(index), String.valueOf(tableCtr.getRowCount())
});
detailsCmp.setText(details);
setDetailsToolbarVisible(true);
}
private void openCourse(UserRequest ureq) {
List<ContextEntry> ces = new ArrayList<ContextEntry>(1);
OLATResourceable ores = OresHelper.createOLATResourceableInstance("RepositoryEntry", courseStat.getRepoKey());
ces.add(BusinessControlFactory.getInstance().createContextEntry(ores));
BusinessControl bc = BusinessControlFactory.getInstance().createFromContextEntries(ces);
WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl());
NewControllerFactory.getInstance().launch(ureq, bwControl);
}
}
/**
* <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.modules.coach.ui;
import java.util.List;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.panel.Panel;
import org.olat.core.gui.components.table.ColumnDescriptor;
import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
import org.olat.core.gui.components.table.DefaultColumnDescriptor;
import org.olat.core.gui.components.table.TableController;
import org.olat.core.gui.components.table.TableDataModel;
import org.olat.core.gui.components.table.TableEvent;
import org.olat.core.gui.components.table.TableGuiConfiguration;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.gui.control.generic.dtabs.Activateable2;
import org.olat.core.id.OLATResourceable;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.StateEntry;
import org.olat.core.util.resource.OresHelper;
import org.olat.modules.coach.CoachingService;
import org.olat.modules.coach.model.CourseStatEntry;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryManager;
import org.olat.modules.coach.ui.CoursesTableDataModel.Columns;
/**
*
* Description:<br>
* Overview of all students under the scrutiny of a coach.
*
* <P>
* Initial Date: 8 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CourseListController extends BasicController implements Activateable2 {
private final Panel content;
private final TableController tableCtr;
private final VelocityContainer mainVC;
private CourseController courseCtrl;
private boolean hasChanged = false;
private final CoachingService coachingService;
private final RepositoryManager repositoryManager;
public CourseListController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl);
coachingService = CoreSpringFactory.getImpl(CoachingService.class);
repositoryManager = CoreSpringFactory.getImpl(RepositoryManager.class);
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setTableEmptyMessage(translate("error.no.found"));
tableConfig.setDownloadOffered(true);
tableConfig.setPreferencesOffered(true, "courseListController");
tableCtr = new TableController(tableConfig, ureq, getWindowControl(), null, null, null, null, true, getTranslator());
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.course.name", Columns.name.ordinal(), "select", getLocale()));
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.countStudents", Columns.countStudents.ordinal(), null, getLocale()));
tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.login", Columns.initialLaunch.ordinal(), null, getLocale(),
ColumnDescriptor.ALIGNMENT_LEFT, new LightIconRenderer()));
tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.passed", Columns.countPassed.ordinal(), null, getLocale(),
ColumnDescriptor.ALIGNMENT_LEFT, new ProgressRenderer(false, getTranslator())));
tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.averageScore", Columns.averageScore.ordinal(), null, getLocale(),
ColumnDescriptor.ALIGNMENT_RIGHT, new ScoreCellRenderer()));
listenTo(tableCtr);
loadModel();
mainVC = createVelocityContainer("course_list");
mainVC.put("coursTable", tableCtr.getInitialComponent());
content = new Panel("courseList");
content.setContent(mainVC);
putInitialPanel(content);
}
private void loadModel() {
List<CourseStatEntry> courseStatistics = coachingService.getCoursesStatistics(getIdentity());
TableDataModel<CourseStatEntry> model = new CoursesTableDataModel(courseStatistics);
tableCtr.setTableDataModel(model);
}
private void reloadModel() {
if(hasChanged) {
loadModel();
hasChanged = false;
}
}
@Override
protected void doDispose() {
//
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
//
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(source == tableCtr) {
if(event instanceof TableEvent) {
TableEvent e = (TableEvent) event;
if("select".equals(e.getActionId())) {
CourseStatEntry courseStat = (CourseStatEntry)tableCtr.getTableDataModel().getObject(e.getRowId());
selectCourse(ureq, courseStat);
}
}
} else if (event == Event.BACK_EVENT) {
reloadModel();
content.setContent(tableCtr.getInitialComponent());
removeAsListenerAndDispose(courseCtrl);
courseCtrl = null;
addToHistory(ureq);
} else if (source == courseCtrl) {
if(event == Event.CHANGED_EVENT) {
hasChanged = true;
} else if("next.course".equals(event.getCommand())) {
nextCourse(ureq);
} else if("previous.course".equals(event.getCommand())) {
previousCourse(ureq);
}
}
super.event(ureq, source, event);
}
@Override
public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
if(entries == null || entries.isEmpty()) return;
ContextEntry ce = entries.get(0);
OLATResourceable ores = ce.getOLATResourceable();
if("RepositoryEntry".equals(ores.getResourceableTypeName())) {
Long repoKey = ores.getResourceableId();
for(int i=tableCtr.getRowCount(); i-->0; ) {
CourseStatEntry courseStat = (CourseStatEntry)tableCtr.getTableDataModel().getObject(i);
if(repoKey.equals(courseStat.getRepoKey())) {
selectCourse(ureq, courseStat);
if(courseCtrl != null) {
courseCtrl.activate(ureq, entries.subList(1, entries.size()), ce.getTransientState());
}
break;
}
}
}
}
protected void previousCourse(UserRequest ureq) {
CourseStatEntry currentEntry = courseCtrl.getEntry();
int previousIndex = tableCtr.getIndexOfSortedObject(currentEntry) - 1;
if(previousIndex < 0 || previousIndex >= tableCtr.getRowCount()) {
previousIndex = tableCtr.getRowCount() - 1;
}
CourseStatEntry previousEntry = (CourseStatEntry)tableCtr.getSortedObjectAt(previousIndex);
selectCourse(ureq, previousEntry);
}
protected void nextCourse(UserRequest ureq) {
CourseStatEntry currentEntry = courseCtrl.getEntry();
int nextIndex = tableCtr.getIndexOfSortedObject(currentEntry) + 1;
if(nextIndex < 0 || nextIndex >= tableCtr.getRowCount()) {
nextIndex = 0;
}
CourseStatEntry nextEntry = (CourseStatEntry)tableCtr.getSortedObjectAt(nextIndex);
selectCourse(ureq, nextEntry);
}
protected void selectCourse(UserRequest ureq, CourseStatEntry courseStat) {
removeAsListenerAndDispose(courseCtrl);
courseCtrl = null;
RepositoryEntry re = repositoryManager.lookupRepositoryEntry(courseStat.getRepoKey(), false);
if(re != null) {
OLATResourceable ores = OresHelper.createOLATResourceableInstance(RepositoryEntry.class, re.getKey());
WindowControl bwControl = addToHistory(ureq, ores, null);
int index = tableCtr.getIndexOfSortedObject(courseStat);
courseCtrl = new CourseController(ureq, bwControl, re, courseStat, index, tableCtr.getRowCount());
listenTo(courseCtrl);
content.setContent(courseCtrl.getInitialComponent());
}
}
}
\ No newline at end of file
/**
* <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.modules.coach.ui;
import java.util.ArrayList;
import java.util.List;
import org.olat.core.gui.components.table.TableDataModel;
import org.olat.modules.coach.model.CourseStatEntry;
import org.olat.modules.coach.ui.ProgressValue;
import org.olat.modules.coach.ui.LightedValue.Light;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 8 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class CoursesTableDataModel implements TableDataModel<CourseStatEntry> {
private List<CourseStatEntry> statistics;
public CoursesTableDataModel(List<CourseStatEntry> cours) {
this.statistics = cours;
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public int getRowCount() {
return statistics == null ? 0 : statistics.size();
}
@Override
public Object getValueAt(int row, int col) {
CourseStatEntry c = statistics.get(row);
switch(Columns.getValueAt(col)) {
case name: {
return c.getRepoDisplayName();
}
case countStudents: {
return new Integer(c.getCountDistinctStudents());
}
case initialLaunch: {
int count = c.getCountDistinctStudents();
if(count == 0) {
return new LightedValue("", Light.grey);
}
int launch = c.getInitialLaunch();
Light light = Light.yellow;
if(launch == count) {
light = Light.green;
} else if (launch == 0) {
light = Light.red;
}
return new LightedValue(Integer.toString(launch), light);
}
case countPassed: {
int numOfStudents = c.getCountDistinctStudents();
if(numOfStudents == 0) {
return numOfStudents;
}
ProgressValue val = new ProgressValue();
val.setTotal(numOfStudents);
val.setGreen(c.getCountPassed());
return val;
}
case countPassedLight: {
int count = c.getCountDistinctStudents();
if(count == 0) {
return new LightedValue("", Light.grey);
}
int passed = c.getCountPassed();
Light light = Light.yellow;
if(passed == count) {
light = Light.green;
} else if (passed == 0) {
light = Light.red;
}
return new LightedValue(Integer.toString(c.getCountPassed()), light);
}
case averageScore: return c.getAverageScore();
}
return null;
}
@Override
public CourseStatEntry getObject(int row) {
return statistics.get(row);
}
@Override
public void setObjects(List<CourseStatEntry> objects) {
statistics = objects;
}
@Override
public CoursesTableDataModel createCopyWithEmptyList() {
return new CoursesTableDataModel(new ArrayList<CourseStatEntry>());
}
public static enum Columns {
name,
countStudents,
initialLaunch,
countPassed,
countPassedLight,
averageScore;
public static Columns getValueAt(int ordinal) {
if(ordinal >= 0 && ordinal < values().length) {
return values()[ordinal];
}
return name;
}
}
}
/**
* <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.modules.coach.ui;
import java.util.Collections;
import java.util.List;
import org.olat.basesecurity.BaseSecurity;
import org.olat.core.CoreSpringFactory;
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.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.gui.control.generic.dtabs.Activateable2;
import org.olat.core.id.Identity;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.StateEntry;
import org.olat.course.CourseFactory;
import org.olat.course.ICourse;
import org.olat.course.assessment.EfficiencyStatement;
import org.olat.course.assessment.EfficiencyStatementController;
import org.olat.course.assessment.EfficiencyStatementManager;
import org.olat.course.assessment.IdentityAssessmentEditController;
import org.olat.course.assessment.UserEfficiencyStatement;
import org.olat.group.BusinessGroup;
import org.olat.modules.coach.model.EfficiencyStatementEntry;
import org.olat.repository.RepositoryEntry;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 9 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class EfficiencyStatementDetailsController extends BasicController implements Activateable2 {
private final VelocityContainer mainVC;
private final SegmentViewComponent segmentView;
private final Link efficiencyStatementLink, assessmentLink;
private boolean hasChanged;
private EfficiencyStatementEntry statementEntry;
private EfficiencyStatementController statementCtrl;
private IdentityAssessmentEditController assessmentCtrl;
private final Identity assessedIdentity;
private final BusinessGroup group;
private final BaseSecurity securityManager;
private final EfficiencyStatementManager efficiencyStatementManager;
public EfficiencyStatementDetailsController(UserRequest ureq, WindowControl wControl,
EfficiencyStatementEntry statementEntry, BusinessGroup group) {
super(ureq, wControl);
efficiencyStatementManager = EfficiencyStatementManager.getInstance();
securityManager = CoreSpringFactory.getImpl(BaseSecurity.class);
mainVC = createVelocityContainer("efficiency_details");
this.group = group;
this.statementEntry = statementEntry;
segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
efficiencyStatementLink = LinkFactory.createLink("details.statement", mainVC, this);
segmentView.addSegment(efficiencyStatementLink, true);
assessmentLink = LinkFactory.createLink("details.assessment", mainVC, this);
segmentView.addSegment(assessmentLink, false);
RepositoryEntry entry = statementEntry.getCourse();
assessedIdentity = securityManager.loadIdentityByKey(statementEntry.getStudentKey());
statementCtrl = createEfficiencyStatementController(ureq);
listenTo(statementCtrl);
if(entry == null) {
assessmentLink.setEnabled(false);
} else {
ICourse course = CourseFactory.loadCourse(entry.getOlatResource());
assessmentCtrl = new IdentityAssessmentEditController(wControl, ureq, null, assessedIdentity, course, true, false);
listenTo(assessmentCtrl);
}
mainVC.put("segmentCmp", statementCtrl.getInitialComponent());
putInitialPanel(mainVC);
}
public EfficiencyStatementEntry getEntry() {
return statementEntry;
}
@Override
protected void doDispose() {
//
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(assessmentCtrl == source) {
if(event == Event.CHANGED_EVENT) {
//reload the details
efficiencyStatementChanged();
hasChanged = true;
fireEvent(ureq, Event.CHANGED_EVENT);
}
} else {
super.event(ureq, source, event);
}
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
if(source == segmentView && event instanceof SegmentViewEvent) {
SegmentViewEvent sve = (SegmentViewEvent)event;
if(efficiencyStatementLink.getComponentName().equals(sve.getComponentName())) {
if(hasChanged) {
//reload
removeAsListenerAndDispose(statementCtrl);
statementCtrl = createEfficiencyStatementController(ureq);
listenTo(statementCtrl);
hasChanged = false;
}
mainVC.put("segmentCmp", statementCtrl.getInitialComponent());
} else if(assessmentLink.getComponentName().equals(sve.getComponentName())) {
mainVC.put("segmentCmp", assessmentCtrl.getInitialComponent());
}
}
}
@Override
public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
//
}
private EfficiencyStatementController createEfficiencyStatementController(UserRequest ureq) {
RepositoryEntry entry = statementEntry.getCourse();
UserEfficiencyStatement statement = statementEntry.getUserEfficencyStatement();
EfficiencyStatement efficiencyStatement = null;
if(statement != null) {
efficiencyStatement = EfficiencyStatementManager.getInstance().getUserEfficiencyStatement(statement.getCourseRepoKey(), assessedIdentity);
}
return new EfficiencyStatementController(getWindowControl(), ureq, assessedIdentity, group, entry, efficiencyStatement, true);
}
private void efficiencyStatementChanged() {
Identity assessedIdentity = securityManager.loadIdentityByKey(statementEntry.getStudentKey());
List<Identity> assessedIdentityList = Collections.singletonList(assessedIdentity);
RepositoryEntry re = statementEntry.getCourse();
efficiencyStatementManager.updateEfficiencyStatements(re.getOlatResource(), assessedIdentityList);
}
}
\ No newline at end of file
/**
* <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.modules.coach.ui;
import java.util.ArrayList;
import java.util.List;
import org.olat.core.gui.components.table.TableDataModel;
import org.olat.course.assessment.UserEfficiencyStatement;
import org.olat.modules.coach.model.EfficiencyStatementEntry;
import org.olat.modules.coach.ui.ProgressValue;
import org.olat.repository.RepositoryEntry;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 8 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class EfficiencyStatementEntryTableDataModel implements TableDataModel<EfficiencyStatementEntry> {
private List<EfficiencyStatementEntry> group;
public EfficiencyStatementEntryTableDataModel(List<EfficiencyStatementEntry> group) {
this.group = group;
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public int getRowCount() {
return group == null ? 0 : group.size();
}
@Override
public Object getValueAt(int row, int col) {
EfficiencyStatementEntry entry = group.get(row);
switch(Columns.getValueAt(col)) {
case studentName: {
return entry.getStudentFullName();
}
case repoName: {
RepositoryEntry re = entry.getCourse();
return re.getDisplayname();
}
case score: {
UserEfficiencyStatement s = entry.getUserEfficencyStatement();
return s == null ? null : s.getScore();
}
case passed: {
UserEfficiencyStatement s = entry.getUserEfficencyStatement();
return s == null ? null : s.getPassed();
}
case progress: {
UserEfficiencyStatement s = entry.getUserEfficencyStatement();
if(s == null || s.getTotalNodes() == null) {
ProgressValue val = new ProgressValue();
val.setTotal(100);
val.setGreen(0);
return val;
}
ProgressValue val = new ProgressValue();
val.setTotal(s.getTotalNodes().intValue());
val.setGreen(s.getAttemptedNodes() == null ? 0 : s.getAttemptedNodes().intValue());
return val;
}
case lastModification: {
UserEfficiencyStatement s = entry.getUserEfficencyStatement();
return s == null ? null : s.getLastModified();
}
}
return null;
}
@Override
public EfficiencyStatementEntry getObject(int row) {
return group.get(row);
}
public int indexOf(EfficiencyStatementEntry obj) {
return group.indexOf(obj);
}
@Override
public void setObjects(List<EfficiencyStatementEntry> objects) {
group = objects;
}
@Override
public EfficiencyStatementEntryTableDataModel createCopyWithEmptyList() {
return new EfficiencyStatementEntryTableDataModel(new ArrayList<EfficiencyStatementEntry>());
}
public static enum Columns {
studentName,
repoName,
score,
passed,
progress,
lastModification,
;
public static Columns getValueAt(int ordinal) {
if(ordinal >= 0 && ordinal < values().length) {
return values()[ordinal];
}
return studentName;
}
}
}
/**
* <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.modules.coach.ui;
import java.util.ArrayList;
import java.util.List;
import org.olat.NewControllerFactory;
import org.olat.core.CoreSpringFactory;
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.table.BooleanColumnDescriptor;
import org.olat.core.gui.components.table.ColumnDescriptor;
import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
import org.olat.core.gui.components.table.DefaultColumnDescriptor;
import org.olat.core.gui.components.table.TableController;
import org.olat.core.gui.components.table.TableDataModel;
import org.olat.core.gui.components.table.TableEvent;
import org.olat.core.gui.components.table.TableGuiConfiguration;
import org.olat.core.gui.components.text.TextComponent;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.gui.control.generic.dtabs.Activateable2;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.id.context.BusinessControl;
import org.olat.core.id.context.BusinessControlFactory;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.StateEntry;
import org.olat.core.util.StringHelper;
import org.olat.core.util.resource.OresHelper;
import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupService;
import org.olat.modules.coach.CoachingService;
import org.olat.modules.coach.model.EfficiencyStatementEntry;
import org.olat.modules.coach.model.GroupStatEntry;
import org.olat.modules.coach.ui.EfficiencyStatementEntryTableDataModel.Columns;
import org.olat.modules.coach.ui.ToolbarController.Position;
/**
*
* Description:<br>
* Overview of all students under the scrutiny of a coach.
*
* <P>
* Initial Date: 8 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class GroupController extends BasicController implements Activateable2 {
private final Link backLink, next, previous;
private final Link nextGroup, previousGroup;
private final Link openGroup;
private final TextComponent detailsCmp, detailsGroupCmp;
private final TableController tableCtr;
private final VelocityContainer mainVC;
private final VelocityContainer groupDetailsVC;
private final ToolbarController toolbar;
private EfficiencyStatementDetailsController statementCtrl;
private boolean hasChanged = false;
private final BusinessGroup group;
private final GroupStatEntry entry;
private final CoachingService coachingService;
private final BusinessGroupService groupManager;
public GroupController(UserRequest ureq, WindowControl wControl, GroupStatEntry groupStatistic, int index, int numOfGroups) {
super(ureq, wControl);
this.entry = groupStatistic;
coachingService = CoreSpringFactory.getImpl(CoachingService.class);
groupManager = CoreSpringFactory.getImpl(BusinessGroupService.class);
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setTableEmptyMessage(translate("error.no.found"));
tableConfig.setDownloadOffered(true);
tableConfig.setPreferencesOffered(true, "groupController");
tableCtr = new TableController(tableConfig, ureq, getWindowControl(), null, null, null, null, true, getTranslator());
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("student.name", Columns.studentName.ordinal(), "select", getLocale()));
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.course.name", Columns.repoName.ordinal(), "select", getLocale()));
tableCtr.addColumnDescriptor(new BooleanColumnDescriptor("table.header.passed", Columns.passed.ordinal(), translate("passed.true"), translate("passed.false")));
tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.score", Columns.score.ordinal(),"select", getLocale(),
ColumnDescriptor.ALIGNMENT_RIGHT, new ScoreCellRenderer()));
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.lastScoreDate", Columns.lastModification.ordinal(), "select", getLocale()));
listenTo(tableCtr);
group = groupManager.loadBusinessGroup(groupStatistic.getGroupKey());
List<EfficiencyStatementEntry> allGroup = loadModel();
mainVC = createVelocityContainer("group_view");
toolbar = new ToolbarController(ureq, wControl, getTranslator());
listenTo(toolbar);
backLink = toolbar.addToolbarLink("back", this, Position.left);
backLink.setCustomEnabledLinkCSS("b_link_back");
//next/previous student
previous = toolbar.addToolbarLink("previous", this, Position.center);
previous.setCustomEnabledLinkCSS("b_with_small_icon_left b_with_small_icon_only b_move_left_icon");
previous.setEnabled(allGroup.size() > 1);
detailsCmp = toolbar.addToolbarText("", this, Position.center);
next = toolbar.addToolbarLink("next", this, Position.center);
next.setCustomEnabledLinkCSS("b_with_small_icon_right b_with_small_icon_only b_move_right_icon");
next.setEnabled(allGroup.size() > 1);
//next/previous group
//students next,previous
previousGroup = toolbar.addToolbarLink("previous.group", this, Position.center);
previousGroup.setCustomEnabledLinkCSS("b_with_small_icon_left b_with_small_icon_only b_move_left_icon");
previousGroup.setEnabled(numOfGroups > 1);
detailsGroupCmp = toolbar.addToolbarText("details.group", "", this, Position.center);
detailsGroupCmp.setText(translate("students.details", new String[]{
StringHelper.escapeHtml(group.getName()), Integer.toString(index + 1), Integer.toString(numOfGroups)
}));
nextGroup = toolbar.addToolbarLink("next.group", this, Position.center);
nextGroup.setCustomEnabledLinkCSS("b_with_small_icon_right b_with_small_icon_only b_move_right_icon");
nextGroup.setEnabled(numOfGroups > 1);
groupDetailsVC = createVelocityContainer("group_details");
groupDetailsVC.contextPut("groupName", StringHelper.escapeHtml(group.getName()));
openGroup = LinkFactory.createButton("open.group", groupDetailsVC, this);
openGroup.setCustomEnabledLinkCSS("b_link_left_icon b_link_group");
groupDetailsVC.put("open", openGroup);
mainVC.put("toolbar", toolbar.getInitialComponent());
mainVC.put("groupDetails", groupDetailsVC);
mainVC.put("groupsTable", tableCtr.getInitialComponent());
setDetailsToolbarVisible(false);
putInitialPanel(mainVC);
}
public GroupStatEntry getEntry() {
return entry;
}
private List<EfficiencyStatementEntry> loadModel() {
List<EfficiencyStatementEntry> allGroup = coachingService.getGroup(group);
TableDataModel<EfficiencyStatementEntry> model = new EfficiencyStatementEntryTableDataModel(allGroup);
tableCtr.setTableDataModel(model);
return allGroup;
}
private void reloadModel() {
if(hasChanged) {
loadModel();
hasChanged = false;
}
}
@Override
protected void doDispose() {
//
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
if (source == next) {
nextEntry(ureq);
} else if (source == previous) {
previousEntry(ureq);
} else if(source == backLink) {
reloadModel();
back(ureq);
} else if(source == openGroup) {
openGroup(ureq);
}
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(source == tableCtr) {
if(event instanceof TableEvent) {
TableEvent e = (TableEvent) event;
if("select".equals(e.getActionId())) {
EfficiencyStatementEntry entry = (EfficiencyStatementEntry)tableCtr.getTableDataModel().getObject(e.getRowId());
selectDetails(ureq, entry);
}
}
} else if (source == toolbar) {
if("back".equals(event.getCommand())) {
reloadModel();
back(ureq);
} else if ("previous".equals(event.getCommand())) {
previousEntry(ureq);
} else if ("next".equals(event.getCommand())) {
nextEntry(ureq);
} else if ("next.group".equals(event.getCommand())) {
fireEvent(ureq, event);
} else if ("previous.group".equals(event.getCommand())) {
fireEvent(ureq, event);
}
} else if (statementCtrl == source) {
if(event == Event.CHANGED_EVENT) {
hasChanged = true;
fireEvent(ureq, event);
}
}
super.event(ureq, source, event);
}
@Override
public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
if(entries == null || entries.isEmpty()) return;
ContextEntry ce = entries.get(0);
OLATResourceable ores = ce.getOLATResourceable();
if("Identity".equals(ores.getResourceableTypeName())) {
Long identityKey = ores.getResourceableId();
for(int i=tableCtr.getRowCount(); i-->0; ) {
EfficiencyStatementEntry entry = (EfficiencyStatementEntry)tableCtr.getTableDataModel().getObject(i);
if(identityKey.equals(entry.getStudentKey())) {
selectDetails(ureq, entry);
statementCtrl.activate(ureq, entries.subList(1, entries.size()), ce.getTransientState());
break;
}
}
}
}
private void setDetailsToolbarVisible(boolean visible) {
next.setVisible(visible);
previous.setVisible(visible);
detailsCmp.setVisible(visible);
nextGroup.setVisible(!visible);
previousGroup.setVisible(!visible);
detailsGroupCmp.setVisible(!visible);
}
private void back(UserRequest ureq) {
if(statementCtrl == null) {
fireEvent(ureq, Event.BACK_EVENT);
} else {
removeDetails(ureq);
}
}
private void previousEntry(UserRequest ureq) {
EfficiencyStatementEntry currentEntry = statementCtrl.getEntry();
int previousIndex = tableCtr.getIndexOfSortedObject(currentEntry) - 1;
if(previousIndex < 0 || previousIndex >= tableCtr.getRowCount()) {
previousIndex = tableCtr.getRowCount() - 1;
}
EfficiencyStatementEntry previousEntry = (EfficiencyStatementEntry)tableCtr.getSortedObjectAt(previousIndex);
selectDetails(ureq, previousEntry);
}
private void nextEntry(UserRequest ureq) {
EfficiencyStatementEntry currentEntry = statementCtrl.getEntry();
int nextIndex = tableCtr.getIndexOfSortedObject(currentEntry) + 1;
if(nextIndex < 0 || nextIndex >= tableCtr.getRowCount()) {
nextIndex = 0;
}
EfficiencyStatementEntry nextEntry = (EfficiencyStatementEntry)tableCtr.getSortedObjectAt(nextIndex);
selectDetails(ureq, nextEntry);
}
private void removeDetails(UserRequest ureq) {
mainVC.remove(statementCtrl.getInitialComponent());
removeAsListenerAndDispose(statementCtrl);
statementCtrl = null;
setDetailsToolbarVisible(false);
addToHistory(ureq);
}
private void selectDetails(UserRequest ureq, EfficiencyStatementEntry entry) {
removeAsListenerAndDispose(statementCtrl);
OLATResourceable ores = OresHelper.createOLATResourceableInstance(Identity.class, entry.getStudentKey());
WindowControl bwControl = addToHistory(ureq, ores, null);
statementCtrl = new EfficiencyStatementDetailsController(ureq, bwControl, entry, group);
listenTo(statementCtrl);
mainVC.put("efficiencyDetails", statementCtrl.getInitialComponent());
int index = tableCtr.getIndexOfSortedObject(entry) + 1;
String details = translate("students.details", new String[]{
entry.getStudentFullName(), String.valueOf(index), String.valueOf(tableCtr.getRowCount())
});
detailsCmp.setText(details);
setDetailsToolbarVisible(true);
}
private void openGroup(UserRequest ureq) {
List<ContextEntry> ces = new ArrayList<ContextEntry>(4);
OLATResourceable ores = OresHelper.createOLATResourceableInstance("BusinessGroup", entry.getGroupKey());
ces.add(BusinessControlFactory.getInstance().createContextEntry(ores));
BusinessControl bc = BusinessControlFactory.getInstance().createFromContextEntries(ces);
WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl());
NewControllerFactory.getInstance().launch(ureq, bwControl);
}
}
/**
* <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.modules.coach.ui;
import java.util.List;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.table.ColumnDescriptor;
import org.olat.core.gui.components.table.CustomRenderColumnDescriptor;
import org.olat.core.gui.components.table.DefaultColumnDescriptor;
import org.olat.core.gui.components.table.TableController;
import org.olat.core.gui.components.table.TableDataModel;
import org.olat.core.gui.components.table.TableEvent;
import org.olat.core.gui.components.table.TableGuiConfiguration;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController;
import org.olat.core.gui.control.generic.dtabs.Activateable2;
import org.olat.core.id.OLATResourceable;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.StateEntry;
import org.olat.core.util.resource.OresHelper;
import org.olat.group.BusinessGroup;
import org.olat.modules.coach.CoachingService;
import org.olat.modules.coach.model.GroupStatEntry;
import org.olat.modules.coach.ui.GroupsTableDataModel.Columns;
/**
*
* Description:<br>
* Overview of all groups under the scrutiny of a coach.
*
* <P>
* Initial Date: 8 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class GroupListController extends BasicController implements Activateable2 {
private final TableController tableCtr;
private final VelocityContainer mainVC;
private GroupController groupCtrl;
private boolean hasChanged = false;
private final CoachingService coachingService;
public GroupListController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl);
coachingService = CoreSpringFactory.getImpl(CoachingService.class);
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setTableEmptyMessage(translate("error.no.found"));
tableConfig.setDownloadOffered(true);
tableConfig.setPreferencesOffered(true, "groupListController");
tableCtr = new TableController(tableConfig, ureq, getWindowControl(), null, null, null, null, true, getTranslator());
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("group.name", Columns.name.ordinal(), "select", getLocale()));
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.countCourses", Columns.countCourses.ordinal(), null, getLocale()));
tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.countStudents", Columns.countStudents.ordinal(), null, getLocale()));
tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.login", Columns.initialLaunch.ordinal(), null, getLocale(),
ColumnDescriptor.ALIGNMENT_LEFT, new LightIconRenderer()));
tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.passed", Columns.countPassed.ordinal(), null, getLocale(),
ColumnDescriptor.ALIGNMENT_LEFT, new ProgressRenderer(false, getTranslator())));
tableCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.averageScore", Columns.averageScore.ordinal(), null, getLocale(),
ColumnDescriptor.ALIGNMENT_RIGHT, new ScoreCellRenderer()));
listenTo(tableCtr);
loadModel();
mainVC = createVelocityContainer("group_list");
mainVC.put("groupsTable", tableCtr.getInitialComponent());
putInitialPanel(mainVC);
}
@Override
protected void doDispose() {
//
}
private void loadModel() {
List<GroupStatEntry> groups = coachingService.getGroupsStatistics(getIdentity());
TableDataModel<GroupStatEntry> model = new GroupsTableDataModel(groups);
tableCtr.setTableDataModel(model);
}
private void reloadModel() {
if(hasChanged) {
loadModel();
hasChanged = false;
}
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
//
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(source == tableCtr) {
if(event instanceof TableEvent) {
TableEvent e = (TableEvent) event;
if("select".equals(e.getActionId())) {
GroupStatEntry groupStatistic = (GroupStatEntry)tableCtr.getTableDataModel().getObject(e.getRowId());
selectGroup(ureq, groupStatistic);
}
}
} else if (event == Event.BACK_EVENT) {
reloadModel();
mainVC.put("groupsTable", tableCtr.getInitialComponent());
removeAsListenerAndDispose(groupCtrl);
groupCtrl = null;
addToHistory(ureq);
} else if (source == groupCtrl) {
if(event == Event.CHANGED_EVENT) {
hasChanged = true;
} else if("next.group".equals(event.getCommand())) {
nextGroup(ureq);
} else if("previous.group".equals(event.getCommand())) {
previousGroup(ureq);
}
}
super.event(ureq, source, event);
}
@Override
public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
if(entries == null || entries.isEmpty()) return;
ContextEntry ce = entries.get(0);
OLATResourceable ores = ce.getOLATResourceable();
if("BusinessGroup".equals(ores.getResourceableTypeName())) {
Long groupKey = ores.getResourceableId();
for(int i=tableCtr.getRowCount(); i-->0; ) {
GroupStatEntry groupStatistic = (GroupStatEntry)tableCtr.getTableDataModel().getObject(i);
if(groupKey.equals(groupStatistic.getGroupKey())) {
selectGroup(ureq, groupStatistic);
groupCtrl.activate(ureq, entries.subList(1, entries.size()), ce.getTransientState());
break;
}
}
}
}
protected void previousGroup(UserRequest ureq) {
GroupStatEntry currentEntry = groupCtrl.getEntry();
int previousIndex = tableCtr.getIndexOfSortedObject(currentEntry) - 1;
if(previousIndex < 0 || previousIndex >= tableCtr.getRowCount()) {
previousIndex = tableCtr.getRowCount() - 1;
}
GroupStatEntry previousEntry = (GroupStatEntry)tableCtr.getSortedObjectAt(previousIndex);
selectGroup(ureq, previousEntry);
}
protected void nextGroup(UserRequest ureq) {
GroupStatEntry currentEntry = groupCtrl.getEntry();
int nextIndex = tableCtr.getIndexOfSortedObject(currentEntry) + 1;
if(nextIndex < 0 || nextIndex >= tableCtr.getRowCount()) {
nextIndex = 0;
}
GroupStatEntry nextEntry = (GroupStatEntry)tableCtr.getSortedObjectAt(nextIndex);
selectGroup(ureq, nextEntry);
}
protected void selectGroup(UserRequest ureq, GroupStatEntry groupStatistic) {
removeAsListenerAndDispose(groupCtrl);
OLATResourceable ores = OresHelper.createOLATResourceableInstance(BusinessGroup.class, groupStatistic.getGroupKey());
WindowControl bwControl = addToHistory(ureq, ores, null);
int index = tableCtr.getIndexOfSortedObject(groupStatistic);
groupCtrl = new GroupController(ureq, bwControl, groupStatistic, index, tableCtr.getRowCount());
listenTo(groupCtrl);
mainVC.put("groupsTable", groupCtrl.getInitialComponent());
}
}
\ No newline at end of file
/**
* <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.modules.coach.ui;
import java.util.ArrayList;
import java.util.List;
import org.olat.core.gui.components.table.TableDataModel;
import org.olat.modules.coach.model.GroupStatEntry;
import org.olat.modules.coach.ui.ProgressValue;
import org.olat.modules.coach.ui.LightedValue.Light;
/**
*
* Description:<br>
*
* <P>
* Initial Date: 8 févr. 2012 <br>
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class GroupsTableDataModel implements TableDataModel<GroupStatEntry> {
private List<GroupStatEntry> groups;
public GroupsTableDataModel(List<GroupStatEntry> groups) {
this.groups = groups;
}
@Override
public int getColumnCount() {
return 6;
}
@Override
public int getRowCount() {
return groups == null ? 0 : groups.size();
}
@Override
public Object getValueAt(int row, int col) {
GroupStatEntry g = groups.get(row);
int numOfStudents = g.getCountStudents();
switch(Columns.getValueAt(col)) {
case name: {
return g.getGroupName();
}
case countCourses: {
return new Integer(g.getCountCourses());
}
case countStudents: {
return new Integer(numOfStudents);
}
case initialLaunch: {
int count = g.getCountCourses() * g.getCountStudents();
if(count == 0) {
return new LightedValue("", Light.grey);
}
int launch = g.getInitialLaunch();
Light light = Light.yellow;
if(launch == count) {
light = Light.green;
} else if (launch == 0) {
light = Light.red;
}
return new LightedValue(Integer.toString(launch), light);
}
case countPassed: {
if(numOfStudents == 0) {
return new LightedValue("", Light.grey);
}
ProgressValue val = new ProgressValue();
val.setTotal(numOfStudents);
val.setGreen(g.getCountPassed());
return val;
}
case countPassedLight: {
if(numOfStudents == 0) {
return new LightedValue("", Light.grey);
}
int passed = g.getCountPassed();
Light light = Light.yellow;
if(passed == numOfStudents) {
light = Light.green;
} else if (passed == 0) {
light = Light.red;
}
return new LightedValue(Integer.toString(passed), light);
}
case averageScore: return g.getAverageScore();
case statistics: {
return g;
}
}
return null;
}
@Override
public GroupStatEntry getObject(int row) {
return groups.get(row);
}
@Override
public void setObjects(List<GroupStatEntry> objects) {
groups = objects;
}
@Override
public GroupsTableDataModel createCopyWithEmptyList() {
return new GroupsTableDataModel(new ArrayList<GroupStatEntry>());
}
public static enum Columns {
name,
countCourses,
countStudents,
initialLaunch,
countPassed,
countPassedLight,
averageScore,
statistics;
public static Columns getValueAt(int ordinal) {
if(ordinal >= 0 && ordinal < values().length) {
return values()[ordinal];
}
return name;
}
}
}
/**
* <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.modules.coach.ui;
import org.olat.core.gui.components.table.CustomCssCellRenderer;
import org.olat.course.assessment.AssessmentHelper;
import org.olat.modules.coach.ui.LightedValue.Light;
/**
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class LightIconRenderer extends CustomCssCellRenderer {
@Override
protected String getCssClass(Object val) {
if(val == null) {
return null;
}
if(val instanceof LightedValue) {
LightedValue lightedVal = (LightedValue)val;
Light light = lightedVal.getLight();
if(light == null) {
return null;
}
switch(light) {
case grey: return "o_black_led";
case green: return "o_green_led";
case yellow: return "o_yellow_led";
case red: return "o_red_led";
case black: return "o_black_led";
default: return null;
}
}
return null;
}
@Override
protected String getCellValue(Object val) {
if(val == null) {
return null;
}
if(val instanceof LightedValue) {
return ((LightedValue)val).getValue();
}
if(val instanceof Float) {
return AssessmentHelper.getRoundedScore((Float)val);
}
return val.toString();
}
@Override
protected String getHoverText(Object val) {
return null;
}
}
/**
* <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.modules.coach.ui;
/**
*
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class LightedValue {
private final String value;
private final Light light;
public LightedValue(String value, Light light) {
this.value = value;
this.light = light;
}
public String getValue() {
return value;
}
public Light getLight() {
return light;
}
public enum Light {
grey,
green,
yellow,
red,
black,
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment