From fe787123f1cff46f9e3af385ce72cf84d072da10 Mon Sep 17 00:00:00 2001 From: srosse <stephane.rosse@frentix.com> Date: Thu, 25 Apr 2019 11:09:47 +0200 Subject: [PATCH] OO-4032: add filter for active curriculum in "My courses" --- .../modules/curriculum/CurriculumService.java | 8 +++ .../curriculum/manager/CurriculumDAO.java | 18 +++++++ .../manager/CurriculumServiceImpl.java | 8 +++ .../ui/CurriculumListController.java | 25 +++++++-- .../ui/CurriculumManagerDataModel.java | 39 +++++++++++++- .../modules/curriculum/ui/CurriculumRow.java | 15 +++++- .../ui/_i18n/LocalStrings_de.properties | 2 + .../ui/_i18n/LocalStrings_en.properties | 2 + .../CurriculumActiveCellRenderer.java | 54 +++++++++++++++++++ 9 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/olat/modules/curriculum/ui/component/CurriculumActiveCellRenderer.java diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumService.java b/src/main/java/org/olat/modules/curriculum/CurriculumService.java index f9b4ce0e901..6237bbd9069 100644 --- a/src/main/java/org/olat/modules/curriculum/CurriculumService.java +++ b/src/main/java/org/olat/modules/curriculum/CurriculumService.java @@ -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. * diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java index 4b925a44234..735988d98a1 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java @@ -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") diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java index a509c633d12..5159c8ea214 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java @@ -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, diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java index 833dc2250e4..3acaeadb333 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java @@ -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 diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java index c0add519624..4c73aab75dd 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumManagerDataModel.java @@ -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"), diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumRow.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumRow.java index 6936fd77a62..7ed28e85b59 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumRow.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumRow.java @@ -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() { diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties index f75e85cc558..27bd2a1f9f8 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties @@ -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 diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties index 8ca8727dffa..2fcefb7a7e6 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties @@ -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 diff --git a/src/main/java/org/olat/modules/curriculum/ui/component/CurriculumActiveCellRenderer.java b/src/main/java/org/olat/modules/curriculum/ui/component/CurriculumActiveCellRenderer.java new file mode 100644 index 00000000000..36ade0af782 --- /dev/null +++ b/src/main/java/org/olat/modules/curriculum/ui/component/CurriculumActiveCellRenderer.java @@ -0,0 +1,54 @@ +/** + * <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>"); + } + } + } +} -- GitLab