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

OO-1593: add group filters, show group list for group tasks...

parent 84953c99
No related branches found
No related tags found
No related merge requests found
Showing
with 505 additions and 59 deletions
......@@ -221,6 +221,8 @@ public interface FlexiTableElement extends FormItem {
*/
public boolean isFilterEnabled();
public List<FlexiTableFilter> getSelectedFilters();
/**
* @return The selected key by the filter, or null if no item is selected
*/
......@@ -294,6 +296,14 @@ public interface FlexiTableElement extends FormItem {
*/
public void collapseExtendedSearch();
/**
* Setup a filter button right of the quick search
* @param label
*/
public void setExtendedFilterButton(String label, List<FlexiTableFilter> extendedFilters);
public List<FlexiTableFilter> getSelectedExtendedFilters();
/**
* Is the details view visible for this particular row?
*/
......
......@@ -134,7 +134,7 @@ public abstract class AbstractFlexiTableRenderer extends DefaultComponentRendere
}
sb.append("</div>");
sb.append("<div class='col-sm-3 col-xs-4 o_table_row_count'>");
sb.append("<div class='col-sm-2 col-xs-4 o_table_row_count'>");
if(ftE.isNumOfRowsEnabled()) {
int rowCount = ftE.getTableDataModel().getRowCount();
if(rowCount == 1) {
......@@ -143,7 +143,7 @@ public abstract class AbstractFlexiTableRenderer extends DefaultComponentRendere
sb.append(rowCount).append(" ").append(ftE.getTranslator().translate("table.entries"));
}
}
sb.append("</div><div class='col-sm-3 col-xs-8'><div class='pull-right'><div class='o_table_tools'>");
sb.append("</div><div class='col-sm-4 col-xs-8'><div class='pull-right'><div class='o_table_tools'>");
boolean empty = ftE.getTableDataModel().getRowCount() == 0;
......@@ -206,6 +206,9 @@ public abstract class AbstractFlexiTableRenderer extends DefaultComponentRendere
if(ftE.getExtendedSearchButton() != null) {
renderFormItem(renderer, sb, ftE.getExtendedSearchButton(), ubu, translator, renderResult, args);
}
if(ftE.getExtendedFilterButton() != null) {
renderFormItem(renderer, sb, ftE.getExtendedFilterButton(), ubu, translator, renderResult, args);
}
sb.append("</div></div>");
} else if(ftE.getExtendedSearchButton() != null) {
renderFormItem(renderer, sb, ftE.getExtendedSearchButton(), ubu, translator, renderResult, args);
......
......@@ -27,6 +27,7 @@ import java.util.Map;
import org.olat.core.commons.persistence.DefaultResultInfos;
import org.olat.core.commons.persistence.ResultInfos;
import org.olat.core.commons.persistence.SortKey;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
import org.olat.core.gui.components.table.TableDataModel;
/**
......@@ -166,11 +167,11 @@ public abstract class DefaultFlexiTableDataSourceModel<U> implements FlexiTableD
}
@Override
public ResultInfos<U> load(String query, List<String> addQueries, int firstResult, int maxResults, SortKey... orderBy) {
return loadDatas(query, addQueries, false, firstResult, maxResults, orderBy);
public ResultInfos<U> load(String query, List<FlexiTableFilter> filters, List<String> addQueries, int firstResult, int maxResults, SortKey... orderBy) {
return loadDatas(query, filters, addQueries, false, firstResult, maxResults, orderBy);
}
private ResultInfos<U> loadDatas(String query, List<String> addQueries, final boolean force, final int firstResult, final int maxResults, SortKey... orderBy) {
private ResultInfos<U> loadDatas(String query, List<FlexiTableFilter> filters, List<String> addQueries, final boolean force, final int firstResult, final int maxResults, SortKey... orderBy) {
if(rows == null) {
rows = new ArrayList<U>();
}
......@@ -198,7 +199,7 @@ public abstract class DefaultFlexiTableDataSourceModel<U> implements FlexiTableD
}
}
ResultInfos<U> newRows = sourceDelegate.getRows(query, addQueries, correctedFirstResult, correctMaxResults, orderBy);
ResultInfos<U> newRows = sourceDelegate.getRows(query, filters, addQueries, correctedFirstResult, correctMaxResults, orderBy);
if(firstResult == 0) {
if(newRows.getObjects().size() < correctMaxResults) {
rowCount = newRows.getObjects().size();
......
/**
* <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.core.gui.components.form.flexible.impl.elements.table;
import java.util.ArrayList;
import java.util.List;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
/**
*
* Initial date: 23.11.2015<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class ExtendedFilterController extends FormBasicController {
private final List<FlexiTableFilter> filters;
public ExtendedFilterController(UserRequest ureq, WindowControl wControl, List<FlexiTableFilter> filters) {
super(ureq, wControl, "extended_filters");
this.filters = new ArrayList<>(filters);
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
int count = 0;
List<ExtendedFilter> filterNames = new ArrayList<>(filters.size());
for(FlexiTableFilter filter:filters) {
String name = "f-" + (++count);
FormLink filterLink = uifactory.addFormLink(name, formLayout, Link.LINK | Link.NONTRANSLATED);
filterLink.setI18nKey(filter.getLabel());
filterLink.setIconLeftCSS(filter.getIconLeftCSS());
filterLink.setUserObject(filter);
filterNames.add(new ExtendedFilter(filter, name));
}
if(formLayout instanceof FormLayoutContainer) {
((FormLayoutContainer)formLayout).contextPut("filters", filterNames);
}
}
@Override
protected void doDispose() {
//
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(source instanceof FormLink) {
FormLink link = (FormLink)source;
Object uobject = link.getUserObject();
if(uobject instanceof FlexiTableFilter) {
FlexiTableFilter filter = (FlexiTableFilter)uobject;
filter.setSelected(!filter.isSelected());
}
}
fireEvent(ureq, Event.DONE_EVENT);
super.formInnerEvent(ureq, source, event);
}
public List<FlexiTableFilter> getFilters() {
List<FlexiTableFilter> selectedFilters = new ArrayList<>();
for(FlexiTableFilter filter:filters) {
if(filter.isSelected()) {
selectedFilters.add(filter);
}
}
return selectedFilters;
}
@Override
protected void formOK(UserRequest ureq) {
//
}
public static final class ExtendedFilter {
private final FlexiTableFilter filter;
private final String componentName;
public ExtendedFilter(FlexiTableFilter filter, String componentName) {
this.filter = filter;
this.componentName = componentName;
}
public FlexiTableFilter getFilter() {
return filter;
}
public boolean isSelected() {
return filter.isSelected();
}
public String getComponentName() {
return componentName;
}
}
}
......@@ -23,6 +23,7 @@ import java.util.List;
import org.olat.core.commons.persistence.ResultInfos;
import org.olat.core.commons.persistence.SortKey;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
/**
*
......@@ -50,6 +51,6 @@ public interface FlexiTableDataSource<U> extends FlexiTableDataModel<U> {
* @param maxResults
* @param orderBy
*/
public ResultInfos<U> load(String query, List<String> addQueries, int firstResult, int maxResults, SortKey... orderBy);
public ResultInfos<U> load(String query, List<FlexiTableFilter> filters, List<String> addQueries, int firstResult, int maxResults, SortKey... orderBy);
}
......@@ -23,6 +23,7 @@ import java.util.List;
import org.olat.core.commons.persistence.ResultInfos;
import org.olat.core.commons.persistence.SortKey;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
/**
*
......@@ -36,5 +37,5 @@ public interface FlexiTableDataSourceDelegate<V> {
public List<V> reload(List<V> rows);
public ResultInfos<V> getRows(String query, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy);
public ResultInfos<V> getRows(String query, List<FlexiTableFilter> filters, List<String> condQueries, int firstResult, int maxResults, SortKey... orderBy);
}
......@@ -26,7 +26,6 @@
package org.olat.core.gui.components.form.flexible.impl.elements.table;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
......@@ -35,7 +34,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.olat.core.commons.persistence.ResultInfos;
import org.olat.core.commons.persistence.SortKey;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
......@@ -67,7 +65,6 @@ import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.ajax.autocompletion.ListProvider;
import org.olat.core.gui.control.generic.closablewrapper.CloseableCalloutWindowController;
import org.olat.core.gui.media.MediaResource;
import org.olat.core.gui.media.ServletUtil;
import org.olat.core.gui.translator.Translator;
import org.olat.core.util.StringHelper;
import org.olat.core.util.UserSession;
......@@ -115,7 +112,9 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
private FormLink customButton, exportButton;
private FormLink searchButton, extendedSearchButton;
private FormLink classicTypeButton, customTypeButton;
private FormLink extendedFilterButton;
private AbstractTextElement searchFieldEl;
private ExtendedFilterController extendedFilterCtrl;
private ExtendedFlexiTableSearchController extendedSearchCtrl;
private final FlexiTableDataModel<?> dataModel;
......@@ -131,6 +130,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
private SortKey[] orderBy;
private FlexiTableSortOptions sortOptions;
private List<FlexiTableFilter> filters;
private List<FlexiTableFilter> extendedFilters;
private Object selectedObj;
private boolean allSelectedNeedLoadOfWholeModel = false;
private Set<Integer> multiSelectedIndex;
......@@ -174,7 +174,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
if(dataSource != null && loadOnStart) {
//preload it
dataSource.load(null, null, 0, pageSize);
dataSource.load(null, null, null, 0, pageSize);
}
}
......@@ -343,6 +343,19 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
return filters != null && filters.size() > 0;
}
@Override
public List<FlexiTableFilter> getSelectedFilters() {
List<FlexiTableFilter> selectedFilters = new ArrayList<>(2);
if(filters != null) {
for(FlexiTableFilter filter:filters) {
if(filter.isSelected()) {
selectedFilters.add(filter);
}
}
}
return selectedFilters;
}
@Override
public String getSelectedFilterKey() {
String key = null;
......@@ -541,6 +554,42 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
}
}
@Override
public void setExtendedFilterButton(String label, List<FlexiTableFilter> extendedFilters) {
if(StringHelper.containsNonWhitespace(label) && extendedFilters != null && extendedFilters.size() > 0) {
this.extendedFilters = extendedFilters;
String dispatchId = component.getDispatchID();
extendedFilterButton = new FormLinkImpl(dispatchId + "_extFilterButton", "rExtFilterButton", "extfilter", Link.BUTTON | Link.NONTRANSLATED);
extendedFilterButton.setI18nKey(label);
extendedFilterButton.setTranslator(translator);
extendedFilterButton.setIconLeftCSS("o_icon o_icon_filter");
components.put("rExtFilterB", extendedFilterButton);
rootFormAvailable(extendedFilterButton);
extendedFilterButton.setElementCssClass("o_sel_flexi_extendedsearch");
} else {
extendedFilterButton = null;
extendedFilters = null;
}
}
@Override
public List<FlexiTableFilter> getSelectedExtendedFilters() {
List<FlexiTableFilter> selectedFilters = new ArrayList<>();
if(extendedFilters != null && extendedFilters.size() > 0) {
for(FlexiTableFilter extendedFilter:extendedFilters) {
if(extendedFilter.isSelected()) {
selectedFilters.add(extendedFilter);
}
}
}
return selectedFilters;
}
public FormLink getExtendedFilterButton() {
return extendedFilterButton;
}
@Override
public boolean isSelectAllEnable() {
return selectAllEnabled;
......@@ -668,7 +717,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
if(dataSource != null) {
int firstResult = currentPage * getPageSize();
int maxResults = getPageSize();
dataSource.load(getSearchText(), getConditionalQueries(), firstResult, maxResults, orderBy);
dataSource.load(getSearchText(), getSelectedFilters(), getConditionalQueries(), firstResult, maxResults, orderBy);
}
component.setDirty(true);
}
......@@ -720,7 +769,6 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
String filter = form.getRequestParameter("filter");
String pagesize = form.getRequestParameter("pagesize");
String checkbox = form.getRequestParameter("chkbox");
ServletUtil.printOutRequestParameters(ureq.getHttpReq());
if("undefined".equals(dispatchuri)) {
evalSearchRequest(ureq);
} else if(StringHelper.containsNonWhitespace(checkbox)) {
......@@ -754,6 +802,9 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
} else if(extendedSearchButton != null
&& extendedSearchButton.getFormDispatchId().equals(dispatchuri)) {
expandExtendedSearch(ureq);
} else if(extendedFilterButton != null
&& extendedFilterButton.getFormDispatchId().equals(dispatchuri)) {
extendedFilterCallout(ureq);
} else if(dispatchuri != null && StringHelper.containsNonWhitespace(filter)) {
doFilter(filter);
} else if(exportButton != null
......@@ -812,6 +863,9 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
} else if(event == Event.DONE_EVENT) {
evalExtendedSearch(ureq);
}
} else if(source == extendedFilterCtrl) {
doExtendedFilter(ureq);
callout.deactivate();
}
}
......@@ -860,7 +914,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
} else if(dataSource != null) {
currentPage = 0;
dataSource.clear();
dataSource.load(null, conditionalQueries, 0, getPageSize(), orderBy);
dataSource.load(null, getSelectedFilters(), conditionalQueries, 0, getPageSize(), orderBy);
}
selectSortOption(sortKey, asc);
......@@ -883,6 +937,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
private void doFilter(String filterKey) {
String selectedFilterKey = null;
FlexiTableFilter selectedFilter = null;
if(filterKey == null) {
for(FlexiTableFilter filter:filters) {
filter.setSelected(false);
......@@ -896,6 +951,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
} else {
filter.setSelected(true);
selectedFilterKey = filterKey;
selectedFilter = filter;
}
} else {
filter.setSelected(false);
......@@ -911,17 +967,31 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
rowCount = -1;
currentPage = 0;
List<String> addQueries = Collections.singletonList(selectedFilterKey);
List<FlexiTableFilter> selectedFilters = Collections.singletonList(selectedFilter);
dataSource.clear();
dataSource.load(null, addQueries, 0, getPageSize(), orderBy);
dataSource.load(null, selectedFilters, null, 0, getPageSize(), orderBy);
}
component.setDirty(true);
}
private void doExtendedFilter(UserRequest ureq) {
if(dataSource != null) {
rowCount = -1;
currentPage = 0;
List<FlexiTableFilter> selectedFilters = new ArrayList<>(extendedFilters);
dataSource.clear();
dataSource.load(null, selectedFilters, null, 0, getPageSize(), orderBy);
}
getRootForm().fireFormEvent(ureq, new FlexiTableSearchEvent(FlexiTableSearchEvent.EXTENDED_FILTER, this,
getSearchText(), getSelectedFilters(), getSelectedExtendedFilters(), getConditionalQueries(), FormEvent.ONCLICK));
}
private void doExport(UserRequest ureq) {
// ensure the all rows are loaded to export
if(dataSource != null) {
dataSource.load(getSearchText(), getConditionalQueries(), 0, -1, orderBy);
dataSource.load(getSearchText(), getSelectedFilters(), getConditionalQueries(), 0, -1, orderBy);
}
MediaResource resource;
......@@ -943,6 +1013,15 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
searchFieldEl.setVisible(false);
}
}
private void extendedFilterCallout(UserRequest ureq) {
extendedFilterCtrl = new ExtendedFilterController(ureq, wControl, extendedFilters);
extendedFilterCtrl.addControllerListener(this);
callout = new CloseableCalloutWindowController(ureq, wControl, extendedFilterCtrl.getInitialComponent(),
extendedFilterButton, "Filter", true, "o_sel_flexi_filter_callout");
callout.activate();
callout.addControllerListener(this);
}
@Override
public void collapseExtendedSearch() {
......@@ -1207,29 +1286,10 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
currentPage = 0;
resetInternComponents();
dataSource.clear();
dataSource.load(search, conditionalQueries, 0, getPageSize(), orderBy);
}
getRootForm().fireFormEvent(ureq, new FlexiTableSearchEvent(eventCmd, this, search, condQueries, FormEvent.ONCLICK));
}
protected ResultInfos<?> doScroll(int firstResult, int maxResults, SortKey... sortKeys) {
boolean same = isOrderByEqual(sortKeys);
if(!same) {
//clear data source
dataSource.clear();
orderBy = sortKeys;
}
return dataSource.load(getSearchText(), getConditionalQueries(), firstResult, maxResults, sortKeys);
}
private boolean isOrderByEqual(SortKey... sortKeys) {
if(orderBy == null &&
(sortKeys == null || sortKeys.length == 0 ||
(sortKeys.length == 1 && sortKeys[0] == null))) {
return true;
dataSource.load(search, getSelectedFilters(), conditionalQueries, 0, getPageSize(), orderBy);
}
return Arrays.equals(orderBy , sortKeys);
getRootForm().fireFormEvent(ureq, new FlexiTableSearchEvent(eventCmd, this,
search, getSelectedFilters(), getSelectedExtendedFilters(), condQueries, FormEvent.ONCLICK));
}
protected void doResetSearch(UserRequest ureq) {
......@@ -1238,7 +1298,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
if(dataSource != null) {
resetInternComponents();
dataSource.clear();
dataSource.load(null, null, 0, getPageSize());
dataSource.load(null, null, null, 0, getPageSize());
} else {
getRootForm().fireFormEvent(ureq, new FlexiTableSearchEvent(this, FormEvent.ONCLICK));
}
......@@ -1248,7 +1308,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
public Set<Integer> getMultiSelectedIndex() {
if(allSelectedNeedLoadOfWholeModel && dataSource != null) {
//ensure the whole data model is loaded
dataSource.load(getSearchText(), getConditionalQueries(), 0, -1);
dataSource.load(getSearchText(), getSelectedFilters(), getConditionalQueries(), 0, -1);
Set<Integer> allIndex = new HashSet<Integer>();
for(int i=dataModel.getRowCount(); i-->0; ) {
allIndex.add(new Integer(i));
......@@ -1350,7 +1410,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
if(dataSource != null) {
dataSource.clear();
int firstResult = currentPage * getPageSize();
dataSource.load(getSearchText(), getConditionalQueries(), firstResult, getPageSize(), orderBy);//reload needed rows
dataSource.load(getSearchText(), getSelectedFilters(), getConditionalQueries(), firstResult, getPageSize(), orderBy);//reload needed rows
} else {
if(dataModel instanceof FilterableFlexiTableModel) {
if(isFilterEnabled()) {
......
......@@ -22,6 +22,7 @@ package org.olat.core.gui.components.form.flexible.impl.elements.table;
import java.util.List;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
/**
......@@ -37,20 +38,28 @@ public class FlexiTableSearchEvent extends FormEvent {
public static final String SEARCH = "ftSearch";
public static final String QUICK_SEARCH = "ftQuickSearch";
public static final String QUICK_SEARCH_KEY_SELECTION = "ftQuickSearchSelectKey";
public static final String EXTENDED_FILTER = "ftEXTENDEDFILTER";
private final String search;
private final List<String> condQueries;
private final List<FlexiTableFilter> filters;
private final List<FlexiTableFilter> extendedFilters;
public FlexiTableSearchEvent(String cmd, FormItem source, String search, List<String> condQueries, int action) {
public FlexiTableSearchEvent(String cmd, FormItem source, String search, List<FlexiTableFilter> filters,
List<FlexiTableFilter> extendedFilters, List<String> condQueries, int action) {
super(cmd, source, action);
this.search = search;
this.filters = filters;
this.condQueries = condQueries;
this.extendedFilters = extendedFilters;
}
public FlexiTableSearchEvent(FormItem source, int action) {
super(RESET, source, action);
this.search = null;
this.filters = null;
this.condQueries = null;
this.extendedFilters = null;
}
public String getSearch() {
......@@ -60,4 +69,12 @@ public class FlexiTableSearchEvent extends FormEvent {
public List<String> getCondQueries() {
return condQueries;
}
public List<FlexiTableFilter> getFilters() {
return filters;
}
public List<FlexiTableFilter> getExtendedFilters() {
return extendedFilters;
}
}
<ul class="list-unstyled">
#foreach($filter in $filters)
<li>#if($filter.selected)<i class="o_icon o_icon_check"> </i> #end$r.render($filter.componentName)</li>
#end
</ul>
\ No newline at end of file
......@@ -196,7 +196,11 @@ public class AssessmentToolManagerImpl implements AssessmentToolManager {
sb.append(" from ").append(IdentityImpl.class.getName()).append(" as ident ")
.append(" inner join ident.user user ")
.append(" where ");
if(params.isAdmin()) {
if(params.getBusinessGroupKeys() != null && params.getBusinessGroupKeys().size() > 0) {
sb.append(" ident.key in (select participant.identity.key from repoentrytogroup as rel, businessgroup bgi, bgroupmember as participant")
.append(" where rel.entry.key=:repoEntryKey and rel.group=bgi.baseGroup and rel.group=participant.group and bgi.key in (:businessGroupKeys) ")
.append(" )");
} else if(params.isAdmin()) {
sb.append(" (ident.key in (select participant.identity.key from repoentrytogroup as rel, bgroupmember as participant")
.append(" where rel.entry.key=:repoEntryKey and rel.group=participant.group")
.append(" and participant.role='").append(GroupRoles.participant.name()).append("'")
......@@ -231,6 +235,9 @@ public class AssessmentToolManagerImpl implements AssessmentToolManager {
if(identityKey != null) {
query.setParameter("searchIdentityKey", identityKey);
}
if(params.getBusinessGroupKeys() != null && params.getBusinessGroupKeys().size() > 0) {
query.setParameter("businessGroupKeys", params.getBusinessGroupKeys());
}
appendUserSearchToQuery(searchArr, query);
return query;
}
......
......@@ -19,6 +19,9 @@
*/
package org.olat.course.assessment.model;
import java.util.List;
import org.olat.modules.assessment.model.AssessmentEntryStatus;
import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback;
import org.olat.repository.RepositoryEntry;
......@@ -39,7 +42,12 @@ public class SearchAssessedIdentityParams {
private final boolean repositoryEntryCoach;
private final boolean businessGroupCoach;
private boolean passed;
private boolean failed;
private List<AssessmentEntryStatus> assessmentStatus;
private String searchString;
private List<Long> businessGroupKeys;
public SearchAssessedIdentityParams(RepositoryEntry entry, RepositoryEntry referenceEntry, String subIdent,
AssessmentToolSecurityCallback secCallback) {
......@@ -87,6 +95,36 @@ public class SearchAssessedIdentityParams {
public void setSearchString(String searchString) {
this.searchString = searchString;
}
public boolean isPassed() {
return passed;
}
public void setPassed(boolean passed) {
this.passed = passed;
}
public boolean isFailed() {
return failed;
}
public void setFailed(boolean failed) {
this.failed = failed;
}
public List<AssessmentEntryStatus> getAssessmentStatus() {
return assessmentStatus;
}
public void setAssessmentStatus(List<AssessmentEntryStatus> assessmentStatus) {
this.assessmentStatus = assessmentStatus;
}
public List<Long> getBusinessGroupKeys() {
return businessGroupKeys;
}
public void setBusinessGroupKeys(List<Long> businessGroupKeys) {
this.businessGroupKeys = businessGroupKeys;
}
}
......@@ -34,6 +34,7 @@ import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
......@@ -49,7 +50,10 @@ 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.id.Identity;
import org.olat.core.util.StringHelper;
import org.olat.core.util.Util;
import org.olat.course.CourseFactory;
import org.olat.course.ICourse;
import org.olat.course.assessment.AssessmentMainController;
import org.olat.course.assessment.AssessmentToolManager;
import org.olat.course.assessment.bulk.PassedCellRenderer;
......@@ -58,6 +62,8 @@ import org.olat.course.assessment.ui.tool.AssessmentIdentitiesCourseTableModel.I
import org.olat.course.certificate.CertificateLight;
import org.olat.course.certificate.CertificatesManager;
import org.olat.course.certificate.ui.DownloadCertificateCellRenderer;
import org.olat.group.BusinessGroup;
import org.olat.modules.assessment.model.AssessmentEntryStatus;
import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback;
import org.olat.modules.coach.CoachingService;
import org.olat.modules.coach.model.EfficiencyStatementEntry;
......@@ -112,7 +118,7 @@ public class AssessmentIdentitiesCourseController extends FormBasicController {
userPropertyHandlers = userManager.getUserPropertyHandlersFor(AssessmentToolConstants.usageIdentifyer, isAdministrativeUser);
initForm(ureq);
loadModel(null);
loadModel(null, null, null);
}
@Override
......@@ -141,11 +147,66 @@ public class AssessmentIdentitiesCourseController extends FormBasicController {
tableEl = uifactory.addTableElement(getWindowControl(), "table", usersTableModel, 20, false, getTranslator(), formLayout);
tableEl.setExportEnabled(true);
tableEl.setSearchEnabled(new AssessedIdentityListProvider(getIdentity(), courseEntry, null, null, assessmentCallback), ureq.getUserSession());
List<FlexiTableFilter> filters = new ArrayList<>();
filters.add(new FlexiTableFilter(translate("filter.passed"), "passed"));
filters.add(new FlexiTableFilter(translate("filter.failed"), "failed"));
filters.add(new FlexiTableFilter(translate("filter.inProgress"), "inProgress"));
filters.add(new FlexiTableFilter(translate("filter.inReview"), "inReview"));
filters.add(new FlexiTableFilter(translate("filter.done"), "done"));
tableEl.setFilters("", filters);
if(assessmentCallback.canAssessBusinessGoupMembers()) {
List<BusinessGroup> coachedGroups = null;;
if(assessmentCallback.isAdmin()) {
ICourse course = CourseFactory.loadCourse(courseEntry);
coachedGroups = course.getCourseEnvironment().getCourseGroupManager().getAllBusinessGroups();
} else {
coachedGroups = assessmentCallback.getCoachedGroups();
}
if(coachedGroups.size() > 0) {
List<FlexiTableFilter> groupFilters = new ArrayList<>();
for(BusinessGroup coachedGroup:coachedGroups) {
groupFilters.add(new FlexiTableFilter(coachedGroup.getName(), coachedGroup.getKey().toString(), "o_icon o_icon_group"));
}
tableEl.setExtendedFilterButton(translate("filter.groups"), groupFilters);
}
}
}
public List<EfficiencyStatementEntry> loadModel(String searchStr) {
public List<EfficiencyStatementEntry> loadModel(String searchStr, List<FlexiTableFilter> filters, List<FlexiTableFilter> extendedFilters) {
SearchAssessedIdentityParams params = new SearchAssessedIdentityParams(courseEntry, null, null, assessmentCallback);
List<AssessmentEntryStatus> assessmentStatus = null;
if(filters != null && filters.size() > 0) {
assessmentStatus = new ArrayList<>(filters.size());
for(FlexiTableFilter filter:filters) {
if("passed".equals(filter.getFilter())) {
params.setPassed(true);
} else if("failed".equals(filter.getFilter())) {
params.setFailed(true);
} else if(AssessmentEntryStatus.isValueOf(filter.getFilter())){
assessmentStatus.add(AssessmentEntryStatus.valueOf(filter.getFilter()));
}
}
}
params.setAssessmentStatus(assessmentStatus);
List<Long> businessGroupKeys = null;
if(extendedFilters != null && extendedFilters.size() > 0) {
businessGroupKeys = new ArrayList<>(extendedFilters.size());
for(FlexiTableFilter extendedFilter:extendedFilters) {
if(StringHelper.isLong(extendedFilter.getFilter())) {
businessGroupKeys.add(Long.parseLong(extendedFilter.getFilter()));
}
}
}
params.setBusinessGroupKeys(businessGroupKeys);
params.setSearchString(searchStr);
List<Identity> assessedIdentities = assessmentToolManager.getAssessedIdentities(getIdentity(), params);
List<EfficiencyStatementEntry> entries = coachingService.getCourse(getIdentity(), courseEntry);
Map<Long,EfficiencyStatementEntry> identityKeyToStatementMap = entries.stream()
......@@ -201,8 +262,7 @@ public class AssessmentIdentitiesCourseController extends FormBasicController {
}
} else if(event instanceof FlexiTableSearchEvent) {
FlexiTableSearchEvent ftse = (FlexiTableSearchEvent)event;
String searchKey = ftse.getSearch();
loadModel(searchKey);
loadModel(ftse.getSearch(), ftse.getFilters(), ftse.getExtendedFilters());
}
}
......
......@@ -31,6 +31,7 @@ import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
......@@ -47,7 +48,10 @@ 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.id.Identity;
import org.olat.core.util.StringHelper;
import org.olat.core.util.Util;
import org.olat.course.CourseFactory;
import org.olat.course.ICourse;
import org.olat.course.assessment.AssessmentMainController;
import org.olat.course.assessment.AssessmentToolManager;
import org.olat.course.assessment.bulk.PassedCellRenderer;
......@@ -56,7 +60,9 @@ import org.olat.course.assessment.ui.tool.AssessmentIdentitiesCourseNodeTableMod
import org.olat.course.nodes.AssessableCourseNode;
import org.olat.course.nodes.CourseNode;
import org.olat.course.nodes.CourseNodeFactory;
import org.olat.group.BusinessGroup;
import org.olat.modules.assessment.AssessmentEntry;
import org.olat.modules.assessment.model.AssessmentEntryStatus;
import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback;
import org.olat.repository.RepositoryEntry;
import org.olat.user.UserManager;
......@@ -115,7 +121,7 @@ public class AssessmentIdentitiesCourseNodeController extends FormBasicControlle
userPropertyHandlers = userManager.getUserPropertyHandlersFor(AssessmentToolConstants.usageIdentifyer, isAdministrativeUser);
initForm(ureq);
updateModel(null);
updateModel(null, null, null);
}
@Override
......@@ -164,11 +170,65 @@ public class AssessmentIdentitiesCourseNodeController extends FormBasicControlle
tableEl = uifactory.addTableElement(getWindowControl(), "table", usersTableModel, 20, false, getTranslator(), formLayout);
tableEl.setExportEnabled(true);
tableEl.setSearchEnabled(new AssessedIdentityListProvider(getIdentity(), courseEntry, referenceEntry, courseNode.getIdent(), assessmentCallback), ureq.getUserSession());
List<FlexiTableFilter> filters = new ArrayList<>();
filters.add(new FlexiTableFilter(translate("filter.passed"), "passed"));
filters.add(new FlexiTableFilter(translate("filter.failed"), "failed"));
filters.add(new FlexiTableFilter(translate("filter.inProgress"), "inProgress"));
filters.add(new FlexiTableFilter(translate("filter.inReview"), "inReview"));
filters.add(new FlexiTableFilter(translate("filter.done"), "done"));
tableEl.setFilters("", filters);
if(assessmentCallback.canAssessBusinessGoupMembers()) {
List<BusinessGroup> coachedGroups = null;;
if(assessmentCallback.isAdmin()) {
ICourse course = CourseFactory.loadCourse(courseEntry);
coachedGroups = course.getCourseEnvironment().getCourseGroupManager().getAllBusinessGroups();
} else {
coachedGroups = assessmentCallback.getCoachedGroups();
}
if(coachedGroups.size() > 0) {
List<FlexiTableFilter> groupFilters = new ArrayList<>();
for(BusinessGroup coachedGroup:coachedGroups) {
groupFilters.add(new FlexiTableFilter(coachedGroup.getName(), coachedGroup.getKey().toString(), "o_icon o_icon_group"));
}
tableEl.setExtendedFilterButton(translate("filter.groups"), groupFilters);
}
}
}
private void updateModel(String searchKey) {
private void updateModel(String searchString, List<FlexiTableFilter> filters, List<FlexiTableFilter> extendedFilters) {
SearchAssessedIdentityParams params = new SearchAssessedIdentityParams(courseEntry, referenceEntry, courseNode.getIdent(), assessmentCallback);
params.setSearchString(searchKey);
List<AssessmentEntryStatus> assessmentStatus = null;
if(filters != null && filters.size() > 0) {
assessmentStatus = new ArrayList<>(filters.size());
for(FlexiTableFilter filter:filters) {
if("passed".equals(filter.getFilter())) {
params.setPassed(true);
} else if("failed".equals(filter.getFilter())) {
params.setFailed(true);
} else if(AssessmentEntryStatus.isValueOf(filter.getFilter())){
assessmentStatus.add(AssessmentEntryStatus.valueOf(filter.getFilter()));
}
}
}
params.setAssessmentStatus(assessmentStatus);
List<Long> businessGroupKeys = null;
if(extendedFilters != null && extendedFilters.size() > 0) {
businessGroupKeys = new ArrayList<>(extendedFilters.size());
for(FlexiTableFilter extendedFilter:extendedFilters) {
if(StringHelper.isLong(extendedFilter.getFilter())) {
businessGroupKeys.add(Long.parseLong(extendedFilter.getFilter()));
}
}
}
params.setBusinessGroupKeys(businessGroupKeys);
params.setSearchString(searchString);
List<Identity> assessedIdentities = assessmentToolManager.getAssessedIdentities(getIdentity(), params);
List<AssessmentEntry> assessmentEntries = assessmentToolManager.getAssessmentEntries(getIdentity(), params, null);
Map<Long,AssessmentEntry> entryMap = new HashMap<>();
......@@ -215,8 +275,7 @@ public class AssessmentIdentitiesCourseNodeController extends FormBasicControlle
}
} else if(event instanceof FlexiTableSearchEvent) {
FlexiTableSearchEvent ftse = (FlexiTableSearchEvent)event;
String searchKey = ftse.getSearch();
updateModel(searchKey);
updateModel(ftse.getSearch(), ftse.getFilters(), ftse.getExtendedFilters());
}
}
......
......@@ -42,7 +42,10 @@ import org.olat.core.util.resource.OresHelper;
import org.olat.course.CourseFactory;
import org.olat.course.ICourse;
import org.olat.course.assessment.AssessmentHelper;
import org.olat.course.nodes.AssessableCourseNode;
import org.olat.course.nodes.CourseNode;
import org.olat.course.nodes.GTACourseNode;
import org.olat.course.run.environment.CourseEnvironment;
import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback;
import org.olat.repository.RepositoryEntry;
......@@ -79,8 +82,6 @@ public class AssessmentIdentitiesCourseTreeController extends BasicController im
menuTree.addListener(this);
mainPanel = new Panel("empty");
LayoutMain3ColsController columLayoutCtr = new LayoutMain3ColsController(ureq, getWindowControl(), menuTree, mainPanel, "course" + course.getResourceableId());
listenTo(columLayoutCtr); // cleanup on dispose
putInitialPanel(columLayoutCtr.getInitialComponent());
......@@ -122,6 +123,12 @@ public class AssessmentIdentitiesCourseTreeController extends BasicController im
ICourse course = CourseFactory.loadCourse(courseEntry);
if(course.getRunStructure().getRootNode().equals(courseNode)) {
currentCtrl = new AssessmentIdentitiesCourseController(ureq, bwControl, stackPanel, courseEntry, assessmentCallback);
} else if(courseNode instanceof AssessableCourseNode && ((AssessableCourseNode)courseNode).isAssessedBusinessGroups()) {
if(courseNode instanceof GTACourseNode) {
CourseEnvironment courseEnv = CourseFactory.loadCourse(courseEntry).getCourseEnvironment();
currentCtrl = ((GTACourseNode)courseNode).getCoachedGroupListController(ureq, getWindowControl(), stackPanel,
courseEnv, assessmentCallback.isAdmin(), assessmentCallback.getCoachedGroups());
}
} else {
currentCtrl = new AssessmentIdentitiesCourseNodeController(ureq, bwControl, stackPanel, courseEntry, courseNode, assessmentCallback);
}
......
......@@ -24,3 +24,10 @@ waiting.review=Pending reviews
no.certificate=Kein Zertifikat vorhanden
elements.to.review=<i class="o_icon o_icon_warning"> </i> {0} pending
sub.details=Details
filter=Filter
filter.passed=Bestanden
filter.failed=Nicht bestanden
filter.inProgress=Gestartet
filter.inReview=Korrigieren
filter.done=Bewertet
filter.groups=Gruppen
......@@ -49,6 +49,12 @@ import org.olat.course.run.userview.UserCourseEnvironment;
* tool.
*/
public interface AssessableCourseNode extends CourseNode {
/**
*
* @return
*/
public boolean isAssessedBusinessGroups();
/**
* @return Returns the maximal score that can be achieved on this node. Throws
......
......@@ -224,6 +224,11 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements
}
}
@Override
public boolean isAssessedBusinessGroups() {
return false;
}
@Override
public Float getMaxScoreConfiguration() {
if (!hasScoreConfigured()) {
......
......@@ -242,6 +242,11 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements
public boolean needsReferenceToARepositoryEntry() {
return false;
}
@Override
public boolean isAssessedBusinessGroups() {
return false;
}
/**
* @see org.olat.course.nodes.AssessableCourseNode#getCutValueConfiguration()
......
......@@ -67,6 +67,7 @@ import org.olat.course.editor.NodeEditController;
import org.olat.course.editor.PublishEvents;
import org.olat.course.editor.StatusDescription;
import org.olat.course.export.CourseEnvironmentMapper;
import org.olat.course.groupsandrights.CourseGroupManager;
import org.olat.course.nodes.gta.GTAManager;
import org.olat.course.nodes.gta.GTAType;
import org.olat.course.nodes.gta.Task;
......@@ -76,6 +77,7 @@ import org.olat.course.nodes.gta.model.TaskDefinition;
import org.olat.course.nodes.gta.model.TaskDefinitionList;
import org.olat.course.nodes.gta.ui.BulkDownloadToolController;
import org.olat.course.nodes.gta.ui.GTAAssessmentDetailsController;
import org.olat.course.nodes.gta.ui.GTACoachedGroupListController;
import org.olat.course.nodes.gta.ui.GTAEditController;
import org.olat.course.nodes.gta.ui.GTAGroupAssessmentToolController;
import org.olat.course.nodes.gta.ui.GTARunController;
......@@ -604,7 +606,12 @@ public class GTACourseNode extends AbstractAccessableCourseNode implements Persi
RepositoryEntry entry = course.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
gtaManager.deleteTaskList(entry, this);
}
@Override
public boolean isAssessedBusinessGroups() {
return GTAType.group.name().equals(getModuleConfiguration().getStringValue(GTACourseNode.GTASK_TYPE));
}
@Override
public boolean hasStatusConfigured() {
return true; // Task Course node has always a status-field
......@@ -768,6 +775,20 @@ public class GTACourseNode extends AbstractAccessableCourseNode implements Persi
BreadcrumbPanel stackPanel, UserCourseEnvironment userCourseEnvironment) {
return new GTAAssessmentDetailsController(ureq, wControl, userCourseEnvironment, this);
}
public GTACoachedGroupListController getCoachedGroupListController(UserRequest ureq, WindowControl wControl,
BreadcrumbPanel stackPanel, CourseEnvironment courseEnv, boolean admin, List<BusinessGroup> coachedGroups) {
List<BusinessGroup> groups;
CourseGroupManager gm = courseEnv.getCourseGroupManager();
if(admin) {
groups = gm.getAllBusinessGroups();
} else {
groups = coachedGroups;
}
groups = CoreSpringFactory.getImpl(GTAManager.class).filterBusinessGroups(groups, this);
return new GTACoachedGroupListController(ureq, wControl, stackPanel, courseEnv, this, groups);
}
@Override
public List<Controller> createAssessmentTools(UserRequest ureq, WindowControl wControl,
......
......@@ -345,6 +345,11 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe
}
return null;
}
@Override
public boolean isAssessedBusinessGroups() {
return false;
}
/**
* @see org.olat.course.nodes.AssessableCourseNode#getCutValueConfiguration()
......
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