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

OO-4032: add filter for active curriculum in "My courses"

parent 0e070b13
No related branches found
No related tags found
No related merge requests found
Showing
with 165 additions and 6 deletions
......@@ -81,6 +81,14 @@ public interface CurriculumService {
*/
public List<Curriculum> getMyCurriculums(Identity identity);
/**
* The list of curriculums the identity participates.
*
* @param identity The identity
* @return A list of curriculums
*/
public List<CurriculumRef> getMyActiveCurriculumRefs(Identity identity);
/**
* Get the list of members of the specified curriculum with their roles.
*
......
......@@ -45,6 +45,7 @@ import org.olat.modules.curriculum.CurriculumRoles;
import org.olat.modules.curriculum.model.CurriculumImpl;
import org.olat.modules.curriculum.model.CurriculumInfos;
import org.olat.modules.curriculum.model.CurriculumSearchParameters;
import org.olat.repository.RepositoryEntryStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -122,6 +123,23 @@ public class CurriculumDAO {
.getResultList();
}
public List<Long> getMyActiveCurriculumKeys(IdentityRef identity) {
QueryBuilder sb = new QueryBuilder(256);
sb.append("select curElement.curriculum.key from curriculumelement curElement")
.append(" inner join curElement.group as bGroup")
.append(" inner join bGroup.members membership")
.append(" where membership.identity.key=:memberKey and membership.role ").in(CurriculumRoles.participant, CurriculumRoles.coach, CurriculumRoles.owner)
.append(" and curElement.status='active' and exists (select v from repoentrytogroup as rel")
.append(" inner join rel.entry as v")
.append(" where curElement.group.key=rel.group.key and v.status ").in(RepositoryEntryStatusEnum.published)
.append(" )");
return dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Long.class)
.setParameter("memberKey", identity.getKey())
.getResultList();
}
public List<Curriculum> search(CurriculumSearchParameters params) {
QueryBuilder sb = new QueryBuilder(256);
sb.append("select cur from curriculum cur")
......
......@@ -28,6 +28,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.olat.basesecurity.GroupMembershipInheritance;
import org.olat.basesecurity.GroupRoles;
......@@ -68,6 +69,7 @@ import org.olat.modules.curriculum.model.CurriculumElementSearchParams;
import org.olat.modules.curriculum.model.CurriculumElementWebDAVInfos;
import org.olat.modules.curriculum.model.CurriculumInfos;
import org.olat.modules.curriculum.model.CurriculumMember;
import org.olat.modules.curriculum.model.CurriculumRefImpl;
import org.olat.modules.curriculum.model.CurriculumSearchParameters;
import org.olat.modules.curriculum.model.SearchMemberParameters;
import org.olat.modules.taxonomy.TaxonomyLevel;
......@@ -256,6 +258,12 @@ public class CurriculumServiceImpl implements CurriculumService, OrganisationDat
return curriculumDao.getMyCurriculums(identity);
}
@Override
public List<CurriculumRef> getMyActiveCurriculumRefs(Identity identity) {
List<Long> curriculumKeys = curriculumDao.getMyActiveCurriculumKeys(identity);
return curriculumKeys.stream().map(CurriculumRefImpl::new).collect(Collectors.toList());
}
@Override
public CurriculumElement createCurriculumElement(String identifier, String displayName, CurriculumElementStatus status,
Date beginDate, Date endDate, CurriculumElementRef parentRef, CurriculumElementType elementType,
......
......@@ -19,6 +19,7 @@
*/
package org.olat.modules.curriculum.ui;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
......@@ -26,6 +27,7 @@ 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.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;
......@@ -41,8 +43,10 @@ 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.curriculum.Curriculum;
import org.olat.modules.curriculum.CurriculumRef;
import org.olat.modules.curriculum.CurriculumService;
import org.olat.modules.curriculum.ui.CurriculumManagerDataModel.CurriculumCols;
import org.olat.modules.curriculum.ui.component.CurriculumActiveCellRenderer;
import org.springframework.beans.factory.annotation.Autowired;
/**
......@@ -81,6 +85,7 @@ public class CurriculumListController extends FormBasicController implements Act
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, CurriculumCols.key));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(CurriculumCols.active, new CurriculumActiveCellRenderer(getTranslator())));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(CurriculumCols.displayName, "select"));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(CurriculumCols.identifier, "select"));
DefaultFlexiColumnModel toolsCol = new DefaultFlexiColumnModel(CurriculumCols.tools);
......@@ -92,15 +97,29 @@ public class CurriculumListController extends FormBasicController implements Act
tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 20, false, getTranslator(), formLayout);
tableEl.setCustomizeColumns(true);
tableEl.setEmtpyTableMessageKey("table.curriculum.empty");
tableEl.setAndLoadPersistedPreferences(ureq, "cur-curriculum-list");
tableEl.setFilters("activity", getFilters(), false);
tableEl.setSelectedFilterKey("active");
tableEl.setAndLoadPersistedPreferences(ureq, "cur-curriculum-list-v2");
}
private List<FlexiTableFilter> getFilters() {
List<FlexiTableFilter> filters = new ArrayList<>(5);
filters.add(new FlexiTableFilter(translate("filter.active"), "active"));
filters.add(new FlexiTableFilter(translate("filter.inactive"), "inactive"));
filters.add(FlexiTableFilter.SPACER);
filters.add(new FlexiTableFilter(translate("show.all"), "all", true));
return filters;
}
private void loadModel() {
List<Curriculum> curriculums = curriculumService.getMyCurriculums(getIdentity());
List<CurriculumRef> activeRefs = curriculumService.getMyActiveCurriculumRefs(getIdentity());
List<Long> activeKeys = activeRefs.stream().map(CurriculumRef::getKey).collect(Collectors.toList());
List<CurriculumRow> rows = curriculums.stream()
.map(CurriculumRow::new).collect(Collectors.toList());
.map(c -> new CurriculumRow(c, activeKeys.contains(c.getKey())))
.collect(Collectors.toList());
tableModel.setObjects(rows);
tableEl.reset(false, false, true);
tableEl.reset(true, true, true);
}
@Override
......
......@@ -19,11 +19,15 @@
*/
package org.olat.modules.curriculum.ui;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import org.olat.core.commons.persistence.SortKey;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FilterableFlexiTableModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel;
......@@ -35,9 +39,10 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFl
*
*/
public class CurriculumManagerDataModel extends DefaultFlexiTableDataModel<CurriculumRow>
implements SortableFlexiTableDataModel<CurriculumRow> {
implements SortableFlexiTableDataModel<CurriculumRow>, FilterableFlexiTableModel {
private final Locale locale;
private List<CurriculumRow> backups;
public CurriculumManagerDataModel(FlexiTableColumnModel columnsModel, Locale locale) {
super(columnsModel);
......@@ -51,7 +56,29 @@ implements SortableFlexiTableDataModel<CurriculumRow> {
super.setObjects(rows);
}
}
@Override
public void filter(String searchString, List<FlexiTableFilter> filters) {
FlexiTableFilter filter = filters == null || filters.isEmpty() || filters.get(0) == null ? null : filters.get(0);
if(filter != null && !filter.isShowAll()) {
List<CurriculumRow> filteredRows;
if("active".equals(filter.getFilter())) {
filteredRows = backups.stream()
.filter(CurriculumRow::isActive)
.collect(Collectors.toList());
} else if("inactive".equals(filter.getFilter())) {
filteredRows = backups.stream()
.filter(node -> !node.isActive())
.collect(Collectors.toList());
} else {
filteredRows = new ArrayList<>(backups);
}
super.setObjects(filteredRows);
} else {
super.setObjects(backups);
}
}
@Override
public Object getValueAt(int row, int col) {
CurriculumRow curriculum = getObject(row);
......@@ -62,6 +89,7 @@ implements SortableFlexiTableDataModel<CurriculumRow> {
public Object getValueAt(CurriculumRow row, int col) {
switch(CurriculumCols.values()[col]) {
case key: return row.getKey();
case active: return row.isActive();
case displayName: return row.getDisplayName();
case identifier: return row.getIdentifier();
case externalId: return row.getExternalId();
......@@ -71,6 +99,12 @@ implements SortableFlexiTableDataModel<CurriculumRow> {
default: return "ERROR";
}
}
@Override
public void setObjects(List<CurriculumRow> objects) {
super.setObjects(objects);
backups = objects;
}
@Override
public CurriculumManagerDataModel createCopyWithEmptyList() {
......@@ -79,6 +113,7 @@ implements SortableFlexiTableDataModel<CurriculumRow> {
public enum CurriculumCols implements FlexiSortableColumnDef {
key("table.header.key"),
active("table.header.active"),
displayName("table.header.displayName"),
identifier("table.header.identifier"),
externalId("table.header.external.id"),
......
......@@ -35,11 +35,13 @@ public class CurriculumRow implements CurriculumRef {
private final Curriculum curriculum;
private final long numOfElements;
private final boolean canManage;
private final boolean active;
private final FormLink toolsLink;
public CurriculumRow(Curriculum curriculum) {
public CurriculumRow(Curriculum curriculum, boolean active) {
this.curriculum = curriculum;
this.active = active;
numOfElements = -1l;
toolsLink = null;
canManage = false;
......@@ -50,6 +52,7 @@ public class CurriculumRow implements CurriculumRef {
numOfElements = infos.getNumOfElements();
toolsLink = null;
canManage = false;
active = false;
}
public CurriculumRow(CurriculumInfos infos, FormLink toolsLink, boolean canManage) {
......@@ -57,6 +60,7 @@ public class CurriculumRow implements CurriculumRef {
numOfElements = infos.getNumOfElements();
this.toolsLink = toolsLink;
this.canManage = canManage;
active = false;
}
@Override
......@@ -87,6 +91,15 @@ public class CurriculumRow implements CurriculumRef {
public boolean canManage() {
return canManage;
}
/**
* The value must be explicitly loaded.
*
* @return True if active
*/
public boolean isActive() {
return active;
}
@Override
public int hashCode() {
......
......@@ -47,6 +47,7 @@ curriculum.element.types=Typen
curriculum.external.id=Externe ID
curriculum.identifier=Bezeichnung
curriculum.in.my.courses.enabled=Curriculum in "Meine Kurse"
curriculum.inactive.explain=Sie haben kein aktives Curriculum Element mit einem publizierten Kurs in diesem Curriculum.
curriculum.key=ID
curriculum.metadata=Metadaten
curriculum.organisation=Organisation
......@@ -92,6 +93,7 @@ tab.resources=Kurse
tab.user.management=Benutzerverwaltung
table.curriculum.element.empty=Curriculum ist leer
table.curriculum.empty=Es steht kein Curriculum zur Verf\u00FCgung
table.header.active=Aktiv
table.header.begin.date=Beginn
table.header.calendars=Stundenplan
table.header.curriculum=Curriculum
......
......@@ -47,6 +47,7 @@ curriculum.element.types=Types
curriculum.external.id=External ID
curriculum.identifier=Identifier
curriculum.in.my.courses.enabled=Curriculum in "My courses"
curriculum.inactive.explain=You don't have an active curriculum element in this curriculum with a published course.
curriculum.key=ID
curriculum.metadata=Metadata
curriculum.organisation=Organisation
......@@ -92,6 +93,7 @@ tab.resources=Courses
tab.user.management=User management
table.curriculum.element.empty=Curriculum is empty
table.curriculum.empty=There are no curriculum available
table.header.active=Active
table.header.begin.date=Begin
table.header.calendars=Calendar
table.header.curriculum=Curriculum
......
/**
* <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.curriculum.ui.component;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent;
import org.olat.core.gui.render.Renderer;
import org.olat.core.gui.render.StringOutput;
import org.olat.core.gui.render.URLBuilder;
import org.olat.core.gui.translator.Translator;
/**
*
* Initial date: 25 avr. 2019<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class CurriculumActiveCellRenderer implements FlexiCellRenderer {
private final Translator translator;
public CurriculumActiveCellRenderer(Translator translator) {
this.translator = translator;
}
@Override
public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source,
URLBuilder ubu, Translator trans) {
if(cellValue instanceof Boolean) {
Boolean active = (Boolean)cellValue;
if(!active.booleanValue()) {
String title = translator.translate("curriculum.inactive.explain");
target.append("<i class='o_icon o_icon_repo_status_closed' title=\"").append(title).append("\"> </i>");
}
}
}
}
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