From 14246f163d3d8e0a74b2ae58a31b64be5b8d5257 Mon Sep 17 00:00:00 2001 From: uhensler <urs.hensler@frentix.com> Date: Mon, 8 Oct 2018 09:18:48 +0200 Subject: [PATCH] OO-3304: Show only available heat map grouping --- .../core/gui/components/util/KeyValues.java | 49 ++++++++- .../analysis/ui/HeatMapController.java | 102 +++++++++++++----- 2 files changed, 123 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/olat/core/gui/components/util/KeyValues.java b/src/main/java/org/olat/core/gui/components/util/KeyValues.java index 6977c80ccd4..c09e99629dc 100644 --- a/src/main/java/org/olat/core/gui/components/util/KeyValues.java +++ b/src/main/java/org/olat/core/gui/components/util/KeyValues.java @@ -48,7 +48,7 @@ public class KeyValues { * @param keyValue */ public void add(KeyValue keyValue) { - keyValues.removeIf(kv -> kv.getKey().equals(keyValue.getKey())); + remove(keyValue.getKey()); keyValues.add(keyValue); } @@ -71,10 +71,29 @@ public class KeyValues { keyValues.set(index, keyValue); } + /** + * Removes the key / value pair with the appropriate key. + * + * @param key + */ + public void remove(String key) { + keyValues.removeIf(kv -> kv.getKey().equals(key)); + } + + /** + * Returns a array of all keys. The method creates a new array every time it is invoked. + * + * @return + */ public String[] keys() { return keyValues.stream().map(KeyValue::getKey).toArray(String[]::new); } + /** + * Returns a array of all values. The method creates a new array every time it is invoked. + * + * @return + */ public String[] values() { return keyValues.stream().map(KeyValue::getValue).toArray(String[]::new); } @@ -87,6 +106,23 @@ public class KeyValues { return keyValues.stream().map(KeyValue::getKey).anyMatch(k -> Objects.equals(k, key)); } + public int size() { + return keyValues.size(); + } + + public boolean isEmpty() { + return keyValues.isEmpty(); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + for (KeyValue keyValue : keyValues) { + builder.append(keyValue.toString()).append(" "); + } + return builder.toString(); + } + public final static class KeyValue { private final String key; @@ -129,6 +165,17 @@ public class KeyValues { return false; return true; } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("["); + builder.append(key); + builder.append(" : "); + builder.append(value); + builder.append("]"); + return builder.toString(); + } } } diff --git a/src/main/java/org/olat/modules/quality/analysis/ui/HeatMapController.java b/src/main/java/org/olat/modules/quality/analysis/ui/HeatMapController.java index 0d4ec374e13..ee4e6e3152b 100644 --- a/src/main/java/org/olat/modules/quality/analysis/ui/HeatMapController.java +++ b/src/main/java/org/olat/modules/quality/analysis/ui/HeatMapController.java @@ -24,6 +24,7 @@ import static org.olat.core.gui.translator.TranslatorHelper.translateAll; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -76,7 +77,11 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class HeatMapController extends FormBasicController implements FilterableController { + private static final String[] EMPTY_ARRAY = {}; private static final String[] INSUFFICIENT_KEYS = new String[] {"heatmap.insufficient.select"}; + private static final Collection<GroupBy> GROUP_BY_TOPICS = Arrays.asList(GroupBy.TOPIC_IDENTITY, + GroupBy.TOPIC_ORGANISATION, GroupBy.TOPIC_CURRICULUM, GroupBy.TOPIC_CURRICULUM_ELEMENT, + GroupBy.TOPIC_REPOSITORY); private SingleSelection groupEl1; private SingleSelection groupEl2; @@ -86,7 +91,7 @@ public class HeatMapController extends FormBasicController implements Filterable private FlexiTableElement tableEl; private FormLayoutContainer legendLayout; - // This list is the master for the sort order + // This list is the master for the sort order of the questions (sliders). private final List<SliderWrapper> sliders; private final AvailableAttributes availableAttributes; private AnalysisSearchParameter searchParams = new AnalysisSearchParameter(); @@ -169,25 +174,16 @@ public class HeatMapController extends FormBasicController implements Filterable String groupPage = velocity_root + "/heatmap_grouping.html"; FormLayoutContainer grouping = FormLayoutContainer.createCustomFormLayout("grouping", getTranslator(), groupPage); flc.add("grouping", grouping); - // Group by - KeyValues groupByKV = initGroupByKeyValues(); - String[] groupKeys = groupByKV.keys(); - String[] groupValues = groupByKV.values(); - if (multiGroupBy.isNoGroupBy()) { - GroupBy groupBy1 = GroupBy.valueOf(groupKeys[0]); - multiGroupBy = MultiGroupBy.of(groupBy1); - } - groupEl1 = uifactory.addDropdownSingleselect("heatmap.group1", grouping, groupKeys, groupValues); + + groupEl1 = uifactory.addDropdownSingleselect("heatmap.group1", grouping, EMPTY_ARRAY, EMPTY_ARRAY); groupEl1.addActionListener(FormEvent.ONCHANGE); - selectGroupBy(groupEl1, multiGroupBy.getGroupBy1()); - groupEl2 = uifactory.addDropdownSingleselect("heatmap.group2", grouping, groupKeys, groupValues); + groupEl2 = uifactory.addDropdownSingleselect("heatmap.group2", grouping, EMPTY_ARRAY, EMPTY_ARRAY); groupEl2.setAllowNoSelection(true); groupEl2.addActionListener(FormEvent.ONCHANGE); - selectGroupBy(groupEl2, multiGroupBy.getGroupBy2()); - groupEl3 = uifactory.addDropdownSingleselect("heatmap.group3", grouping, groupKeys, groupValues); + groupEl3 = uifactory.addDropdownSingleselect("heatmap.group3", grouping, EMPTY_ARRAY, EMPTY_ARRAY); groupEl3.setAllowNoSelection(true); groupEl3.addActionListener(FormEvent.ONCHANGE); - selectGroupBy(groupEl3, multiGroupBy.getGroupBy3()); + updateGroupingUI(); // Insufficient filter insufficientEl = uifactory.addCheckboxesVertical("heatmap.insufficient", grouping, INSUFFICIENT_KEYS, @@ -199,20 +195,31 @@ public class HeatMapController extends FormBasicController implements Filterable insufficientEl.setVisible(insufficientConfigured); // Heat map - initTable(Collections.emptyList(), 0); - + updateTable(Collections.emptyList(), 0); } - - private void selectGroupBy(SingleSelection groupEl, GroupBy groupBy) { - if (groupBy != null) { - String groupByKey = groupBy.name(); - if (Arrays.asList(groupEl.getKeys()).contains(groupByKey)) { - groupEl.select(groupByKey, true); - } + + private void updateGroupingUI() { + KeyValues groupByKV1 = initGroupByKeyValues(groupEl1); + String[] groupKeys1 = groupByKV1.keys(); + if (multiGroupBy.isNoGroupBy()) { + GroupBy groupBy1 = GroupBy.valueOf(groupKeys1[0]); + multiGroupBy = MultiGroupBy.of(groupBy1); } + groupEl1.setKeysAndValues(groupKeys1, groupByKV1.values(), null); + selectGroupBy(groupEl1, multiGroupBy.getGroupBy1()); + + KeyValues groupByKV2 = initGroupByKeyValues(groupEl2); + groupEl2.setKeysAndValues(groupByKV2.keys(), groupByKV2.values(), null); + groupEl2.setVisible(!groupByKV2.isEmpty()); + selectGroupBy(groupEl2, multiGroupBy.getGroupBy2()); + + KeyValues groupByKV3 = initGroupByKeyValues(groupEl3); + groupEl3.setKeysAndValues(groupByKV3.keys(), groupByKV3.values(), null); + groupEl3.setVisible(!groupByKV3.isEmpty()); + selectGroupBy(groupEl3, multiGroupBy.getGroupBy3()); } - private KeyValues initGroupByKeyValues() { + private KeyValues initGroupByKeyValues(SingleSelection groupEl) { KeyValues keyValues = new KeyValues(); if (availableAttributes.isTopicIdentity()) { addEntry(keyValues, GroupBy.TOPIC_IDENTITY); @@ -244,6 +251,10 @@ public class HeatMapController extends FormBasicController implements Filterable if (availableAttributes.isContextLocation()) { addEntry(keyValues, GroupBy.CONTEXT_LOCATION); } + Collection<GroupBy> elsewhereSelected = getElsewhereSelected(groupEl); + for (GroupBy groupBy : elsewhereSelected) { + keyValues.remove(groupBy.name()); + } return keyValues; } @@ -251,7 +262,43 @@ public class HeatMapController extends FormBasicController implements Filterable keyValues.add(KeyValues.entry(groupBy.name(), translate(groupBy.i18nKey()))); } - private void initTable(List<String> groupHeaders, int maxCount) { + private Collection<GroupBy> getElsewhereSelected(SingleSelection groupEl) { + Collection<GroupBy> elsewhereSelected = new ArrayList<>(2); + if (groupEl != groupEl1 && multiGroupBy.getGroupBy1() != null) { + elsewhereSelected.addAll(ammendTopics(multiGroupBy.getGroupBy1())); + } + if (groupEl != groupEl2 && multiGroupBy.getGroupBy2() != null) { + elsewhereSelected.addAll(ammendTopics(multiGroupBy.getGroupBy2())); + } + if (groupEl != groupEl3 && multiGroupBy.getGroupBy3() != null) { + elsewhereSelected.addAll(ammendTopics(multiGroupBy.getGroupBy3())); + } + return elsewhereSelected; + } + + /** + * A data collection has never multiple topics. So a grouping by multiple topics makes no sense. + * + * @param groupBy + * @return + */ + private Collection<? extends GroupBy> ammendTopics(GroupBy groupBy) { + if (GROUP_BY_TOPICS.contains(groupBy)) { + return GROUP_BY_TOPICS; + } + return Collections.singletonList(groupBy); + } + + private void selectGroupBy(SingleSelection groupEl, GroupBy groupBy) { + if (groupBy != null) { + String groupByKey = groupBy.name(); + if (Arrays.asList(groupEl.getKeys()).contains(groupByKey)) { + groupEl.select(groupByKey, true); + } + } + } + + private void updateTable(List<String> groupHeaders, int maxCount) { int columnIndex = 0; FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); if (groupHeaders.isEmpty()) { @@ -316,6 +363,7 @@ public class HeatMapController extends FormBasicController implements Filterable GroupBy groupBy3 = groupEl3.isOneSelected()? GroupBy.valueOf(groupEl3.getSelectedKey()): null; multiGroupBy = MultiGroupBy.of(groupBy1, groupBy2, groupBy3); fireEvent(ureq, new AnalysisGroupingEvent(multiGroupBy)); + updateGroupingUI(); } private void setInsufficientOnly(UserRequest ureq) { @@ -385,7 +433,7 @@ public class HeatMapController extends FormBasicController implements Filterable List<String> headers = getHeaders(); int maxCount = getMaxCount(rows); - initTable(headers, maxCount); + updateTable(headers, maxCount); rows.sort(new GroupNameAlphabeticalComparator()); dataModel.setObjects(rows); -- GitLab