diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties index 584a759fcb9cd2a5978ae4cd72c86a510489157c..c754a503a8a0c81095e937fa9b41e1b6976a7dbe 100644 --- a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties @@ -357,6 +357,7 @@ filter.current.courses=Aktuelle Kurse filter.not.booked=Nicht belegt filter.not.passed=Nicht bestanden filter.old.courses=Beendete Kurse +filter.only.courses=Nur Kurse filter.passed=Bestanden filter.selected=\u2713 filter.show.all=Alle anzeigen diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties index 6b66b381f5ecce57d5adca5d767c1eb573f196e4..6df05f3bbd907f7738d81f270fd1ef083169b615 100644 --- a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties @@ -357,6 +357,7 @@ filter.current.courses=Current courses filter.not.booked=Not booked filter.not.passed=Not passed filter.old.courses=Finished courses +filter.only.courses=Only courses filter.passed=Passed filter.selected=\u2713 filter.show.all=Show all diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseQueries.java b/src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseQueries.java index fb19ea2afcfe78a80dc464b3c256fdee95b067c6..db4e762ac375ed6a74d5ac67cd75ef5fd5d10b76 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseQueries.java +++ b/src/main/java/org/olat/repository/manager/RepositoryEntryMyCourseQueries.java @@ -438,6 +438,9 @@ public class RepositoryEntryMyCourseQueries { boolean needIdentityKey = false; switch(filter) { case showAll: break; + case onlyCourses: + sb.append(" and res.resName='CourseModule'"); + break; case currentCourses: sb.append(" and lifecycle.validFrom<=:now and lifecycle.validTo>=:now"); break; @@ -615,6 +618,10 @@ public class RepositoryEntryMyCourseQueries { sb.append(" order by lifecycle.validTo "); appendAsc(sb, asc).append(" nulls last, lower(v.displayname) asc"); break; + case type: + sb.append(" order by res.resName "); + appendAsc(sb, asc).append(", lower(v.displayname) asc"); + break; default: if(asc) { sb.append(" order by lower(v.displayname) asc, lifecycle.validFrom desc nulls last, lower(v.externalRef) asc nulls last"); diff --git a/src/main/java/org/olat/repository/model/SearchMyRepositoryEntryViewParams.java b/src/main/java/org/olat/repository/model/SearchMyRepositoryEntryViewParams.java index 64003cfa810ed3fd1e5fad0d0ce83587cc7e61f8..c74fa6316d090b634d7e7003c28a6a1c66c8b2bc 100644 --- a/src/main/java/org/olat/repository/model/SearchMyRepositoryEntryViewParams.java +++ b/src/main/java/org/olat/repository/model/SearchMyRepositoryEntryViewParams.java @@ -152,7 +152,7 @@ public class SearchMyRepositoryEntryViewParams { } public boolean isResourceTypesDefined() { - return resourceTypes != null && resourceTypes.size() > 0; + return resourceTypes != null && !resourceTypes.isEmpty(); } public List<String> getResourceTypes() { @@ -165,7 +165,7 @@ public class SearchMyRepositoryEntryViewParams { public void addResourceTypes(String... types) { if(this.resourceTypes == null) { - this.resourceTypes = new ArrayList<String>(); + this.resourceTypes = new ArrayList<>(); } if(types != null) { for(String resourceType:types) { @@ -220,10 +220,12 @@ public class SearchMyRepositoryEntryViewParams { lifecycleSoftkey, lifecycleStart, lifecycleEnd, + type } public enum Filter { showAll, + onlyCourses, currentCourses, oldCourses, upcomingCourses, diff --git a/src/main/java/org/olat/repository/ui/author/TypeRenderer.java b/src/main/java/org/olat/repository/ui/author/TypeRenderer.java index 05cf701b9381209a481c168a7e93373ea49dd30e..d2b2db07591a3da6d555a2de7e80f6fd15b234e3 100644 --- a/src/main/java/org/olat/repository/ui/author/TypeRenderer.java +++ b/src/main/java/org/olat/repository/ui/author/TypeRenderer.java @@ -31,6 +31,7 @@ import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryShort; import org.olat.repository.RepositoryEntryStatusEnum; import org.olat.repository.ui.RepositoyUIFactory; +import org.olat.repository.ui.list.RepositoryEntryRow; /** * @@ -49,6 +50,8 @@ public class TypeRenderer implements FlexiCellRenderer { type = ((RepositoryEntryShort)cellValue).getResourceType(); } else if(cellValue instanceof RepositoryEntry) { type = ((RepositoryEntry)cellValue).getOlatResource().getResourceableTypeName(); + } else if(cellValue instanceof RepositoryEntryRow) { + type = ((RepositoryEntryRow)cellValue).getOLATResourceable().getResourceableTypeName(); } if(type == null) { @@ -74,6 +77,11 @@ public class TypeRenderer implements FlexiCellRenderer { cssClass = RepositoyUIFactory.getIconCssClass(re); managed = StringHelper.containsNonWhitespace(re.getManagedFlagsString()); status = re.getEntryStatus(); + } else if (cellValue instanceof RepositoryEntryRow) { + RepositoryEntryRow re = (RepositoryEntryRow) cellValue; + cssClass = RepositoyUIFactory.getIconCssClass(re.getOLATResourceable().getResourceableTypeName()); + managed = false;// no indication for this type of row + status = re.getStatus(); } if(renderer == null) { diff --git a/src/main/java/org/olat/repository/ui/list/FilterPreferences.java b/src/main/java/org/olat/repository/ui/list/FilterPreferences.java new file mode 100644 index 0000000000000000000000000000000000000000..632c6d6dcf3bcd245bdd83eabc5de10983b5cbb3 --- /dev/null +++ b/src/main/java/org/olat/repository/ui/list/FilterPreferences.java @@ -0,0 +1,57 @@ +/** + * <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.repository.ui.list; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter; + +/** + * + * Initial date: 28 mai 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class FilterPreferences implements Serializable { + + private static final long serialVersionUID = 8728874712044271508L; + private List<String> selectedFilters = new ArrayList<>(); + + public List<String> getSelectedFilters() { + return selectedFilters; + } + + public void setSelectedFilters(List<String> selectedFilters) { + this.selectedFilters = selectedFilters; + } + + public static FilterPreferences valueOf(List<FlexiTableFilter> filters) { + List<String> filterList = new ArrayList<>(filters.size()); + for(FlexiTableFilter filter:filters) { + filterList.add(filter.getFilter()); + } + + FilterPreferences prefs = new FilterPreferences(); + prefs.setSelectedFilters(filterList); + return prefs; + } +} diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDataModel.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDataModel.java index 19bb23e1f31373ed0be135cb7ffd1a814cecc603..272ded750b0d408e05589ca9870e78c39f32945a 100644 --- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryDataModel.java +++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryDataModel.java @@ -73,6 +73,7 @@ class RepositoryEntryDataModel extends DefaultFlexiTableDataSourceModel<Reposito case details: return item.getDetailsLink(); case ratings: return item.getRatingFormItem(); case comments: return item.getCommentsLink(); + case type: return item; } return null; } @@ -92,7 +93,8 @@ class RepositoryEntryDataModel extends DefaultFlexiTableDataSourceModel<Reposito start("table.header.start"), mark("table.header.mark"), ratings("ratings"), - comments("comments"); + comments("comments"), + type("table.header.typeimg"); private final String i18nKey; diff --git a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java index b6c93b65837a62693081c998a4425a1c40d72c6a..bd0243fbac356c7255dad108c13472ec2194f6b3 100644 --- a/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java +++ b/src/main/java/org/olat/repository/ui/list/RepositoryEntryListController.java @@ -49,6 +49,7 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiColum import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponentDelegate; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableFilterEvent; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableRendererType; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableSearchEvent; import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; @@ -83,6 +84,7 @@ import org.olat.repository.model.SearchMyRepositoryEntryViewParams; import org.olat.repository.model.SearchMyRepositoryEntryViewParams.Filter; import org.olat.repository.model.SearchMyRepositoryEntryViewParams.OrderBy; import org.olat.repository.ui.RepositoryEntryImageMapper; +import org.olat.repository.ui.author.TypeRenderer; import org.olat.repository.ui.list.RepositoryEntryDataModel.Cols; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; @@ -175,7 +177,8 @@ public class RepositoryEntryListController extends FormBasicController if(!guestOnly) { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.mark.i18nKey(), Cols.mark.ordinal(), true, OrderBy.favorit.name())); } - + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(true, Cols.type.i18nKey(), Cols.type.ordinal(), true, OrderBy.type.name(), + FlexiColumnModel.ALIGNMENT_LEFT, new TypeRenderer())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.displayName.i18nKey(), Cols.select.ordinal(), true, OrderBy.displayname.name())); if(repositoryModule.isManagedRepositoryEntries()) { @@ -220,13 +223,15 @@ public class RepositoryEntryListController extends FormBasicController initFilters(tableEl); initSorters(tableEl); - tableEl.setAndLoadPersistedPreferences(ureq, "re-list-" + name); + tableEl.setAndLoadPersistedPreferences(ureq, "re-list-v2-".concat(name)); + loadFilterPreferences(ureq); } private void initFilters(FlexiTableElement tableElement) { List<FlexiTableFilter> filters = new ArrayList<>(16); filters.add(new FlexiTableFilter(translate("filter.show.all"), Filter.showAll.name(), true)); filters.add(FlexiTableFilter.SPACER); + filters.add(new FlexiTableFilter(translate("filter.only.courses"), Filter.onlyCourses.name())); filters.add(new FlexiTableFilter(translate("filter.current.courses"), Filter.currentCourses.name())); filters.add(new FlexiTableFilter(translate("filter.upcoming.courses"), Filter.upcomingCourses.name())); filters.add(new FlexiTableFilter(translate("filter.old.courses"), Filter.oldCourses.name())); @@ -265,6 +270,22 @@ public class RepositoryEntryListController extends FormBasicController options.setDefaultOrderBy(new SortKey(OrderBy.title.name(), true)); tableElement.setSortSettings(options); } + + private void loadFilterPreferences(UserRequest ureq) { + FilterPreferences prefs = (FilterPreferences)ureq.getUserSession().getGuiPreferences() + .get(RepositoryEntryListController.class, "rev-filters-".concat(name)); + if(prefs != null && prefs.getSelectedFilters() != null) { + for(String selectedFilter:prefs.getSelectedFilters()) { + tableEl.setSelectedFilterKey(selectedFilter); + } + } + } + + private void saveFilterPreferences(UserRequest ureq, List<FlexiTableFilter> filters) { + ureq.getUserSession().getGuiPreferences() + .putAndSave(RepositoryEntryListController.class, "rev-filters-".concat(name), + FilterPreferences.valueOf(filters)); + } @Override public String getMapperThumbnailUrl() { @@ -346,6 +367,9 @@ public class RepositoryEntryListController extends FormBasicController RepositoryEntryListState state = new RepositoryEntryListState(); state.setTableState(tableEl.getStateEntry()); addToHistory(ureq, state); + } else if(event instanceof FlexiTableFilterEvent) { + FlexiTableFilterEvent ftfe = (FlexiTableFilterEvent)event; + saveFilterPreferences(ureq, ftfe.getFilters()); } } super.formInnerEvent(ureq, source, event); @@ -373,7 +397,7 @@ public class RepositoryEntryListController extends FormBasicController selectedFilters.add((Filter)filter.getUserObject()); } } - doFilter(selectedFilters); + doFilter(ureq, selectedFilters); flc.setDirty(true); } } else if(source == mainForm.getInitialComponent()) { @@ -381,7 +405,7 @@ public class RepositoryEntryListController extends FormBasicController String rowKeyStr = ureq.getParameter("select_row"); if(StringHelper.isLong(rowKeyStr)) { try { - Long rowKey = new Long(rowKeyStr); + Long rowKey = Long.valueOf(rowKeyStr); List<RepositoryEntryRow> rows = model.getObjects(); for(RepositoryEntryRow row:rows) { if(row != null && row.getKey().equals(rowKey)) { @@ -481,7 +505,7 @@ public class RepositoryEntryListController extends FormBasicController addToHistory(ureq, state); } - protected void doFilter(List<Filter> filters) { + protected void doFilter(UserRequest ureq, List<Filter> filters) { dataSource.setFilters(filters); tableEl.reset(); }