Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 470eda2

Browse files
author
barnabartha
committed
SORMAS-Foundation#3368 - add sub tab layer to campaign dashboard
1 parent 6deed0e commit 470eda2

3 files changed

Lines changed: 142 additions & 80 deletions

File tree

sormas-ui/src/main/java/de/symeda/sormas/ui/dashboard/campaigns/CampaignDashboardDataProvider.java

Lines changed: 75 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.List;
77
import java.util.Map;
88
import java.util.Optional;
9+
import java.util.stream.Collectors;
910

1011
import de.symeda.sormas.api.FacadeProvider;
1112
import de.symeda.sormas.api.campaign.CampaignReferenceDto;
@@ -24,56 +25,76 @@ public class CampaignDashboardDataProvider {
2425
private RegionReferenceDto region;
2526
private DistrictReferenceDto district;
2627

28+
private final Map<CampaignReferenceDto, List<CampaignDashboardDiagramDto>> campaignDiagramDefinitionsMap = new HashMap<>();
29+
2730
private final Map<CampaignDashboardDiagramDto, List<CampaignDiagramDataDto>> campaignFormDataMap = new HashMap<>();
2831
private final Map<CampaignDashboardDiagramDto, Map<CampaignDashboardTotalsReference, Double>> campaignFormTotalsMap = new HashMap<>();
2932

30-
public void refreshData() {
31-
campaignFormDataMap.clear();
32-
campaignFormTotalsMap.clear();
33-
34-
FacadeProvider.getCampaignFacade().validate(campaign);
35-
36-
final List<CampaignDashboardElement> campaignDashboardElements =
37-
FacadeProvider.getCampaignFacade().getCampaignDashboardElements(campaign != null ? campaign.getUuid() : null);
38-
final List<CampaignDiagramDefinitionDto> campaignDiagramDefinitions = FacadeProvider.getCampaignDiagramDefinitionFacade().getAll();
33+
public void refreshDashboardData() {
3934

40-
final List<CampaignDashboardDiagramDto> campaignDashboardDiagramDtos = new ArrayList<>();
41-
42-
campaignDashboardElements.stream().sorted(Comparator.comparingInt(CampaignDashboardElement::getOrder)).forEach(campaignDashboardElement -> {
43-
final Optional<CampaignDiagramDefinitionDto> first = campaignDiagramDefinitions.stream()
44-
.filter(campaignDiagramDefinitionDto -> campaignDiagramDefinitionDto.getDiagramId().equals(campaignDashboardElement.getDiagramId()))
45-
.findFirst();
46-
if (first.isPresent()) {
47-
CampaignDiagramDefinitionDto campaignDiagramDefinitionDto = first.get();
48-
campaignDashboardDiagramDtos.add(new CampaignDashboardDiagramDto(campaignDashboardElement, campaignDiagramDefinitionDto));
49-
}
50-
});
35+
if (campaign != null) {
36+
FacadeProvider.getCampaignFacade().validate(campaign);
37+
createCampaignDashboardDiagramDefinitionsMap();
38+
}
39+
}
5140

52-
campaignDashboardDiagramDtos.forEach(campaignDashboardDiagramDto -> {
53-
List<CampaignDiagramDataDto> diagramData = FacadeProvider.getCampaignFormDataFacade()
54-
.getDiagramData(
55-
campaignDashboardDiagramDto.getCampaignDiagramDefinitionDto().getCampaignDiagramSeries(),
56-
new CampaignDiagramCriteria(campaign, area, region, district));
57-
campaignFormDataMap.put(campaignDashboardDiagramDto, diagramData);
41+
protected void refreshDiagramsData(String tabId, String subTabId) {
42+
campaignFormDataMap.clear();
43+
campaignFormTotalsMap.clear();
5844

59-
if (campaignDashboardDiagramDto.getCampaignDiagramDefinitionDto().getCampaignSeriesTotal() != null) {
60-
List<CampaignDiagramDataDto> percentageDiagramData = FacadeProvider.getCampaignFormDataFacade()
45+
campaignDiagramDefinitionsMap.get(campaign).forEach(campaignDashboardDiagramDto -> {
46+
final CampaignDashboardElement campaignDashboardElement = campaignDashboardDiagramDto.getCampaignDashboardElement();
47+
if (campaignDashboardElement.getTabId().equals(tabId) && (subTabId == null || campaignDashboardElement.getSubTabId().equals(subTabId))) {
48+
List<CampaignDiagramDataDto> diagramData = FacadeProvider.getCampaignFormDataFacade()
6149
.getDiagramData(
62-
campaignDashboardDiagramDto.getCampaignDiagramDefinitionDto().getCampaignSeriesTotal(),
50+
campaignDashboardDiagramDto.getCampaignDiagramDefinitionDto().getCampaignDiagramSeries(),
6351
new CampaignDiagramCriteria(campaign, area, region, district));
64-
65-
Map<CampaignDashboardTotalsReference, Double> percentageMap = new HashMap<>();
66-
for (CampaignDiagramDataDto data : percentageDiagramData) {
67-
CampaignDashboardTotalsReference totals = new CampaignDashboardTotalsReference(data.getGroupingKey(), data.getStack());
68-
Double value = percentageMap.getOrDefault(totals, 0D);
69-
value += data.getValueSum().doubleValue();
70-
percentageMap.put(totals, value);
52+
campaignFormDataMap.put(campaignDashboardDiagramDto, diagramData);
53+
54+
if (campaignDashboardDiagramDto.getCampaignDiagramDefinitionDto().getCampaignSeriesTotal() != null) {
55+
List<CampaignDiagramDataDto> percentageDiagramData = FacadeProvider.getCampaignFormDataFacade()
56+
.getDiagramData(
57+
campaignDashboardDiagramDto.getCampaignDiagramDefinitionDto().getCampaignSeriesTotal(),
58+
new CampaignDiagramCriteria(campaign, area, region, district));
59+
60+
Map<CampaignDashboardTotalsReference, Double> percentageMap = new HashMap<>();
61+
for (CampaignDiagramDataDto data : percentageDiagramData) {
62+
CampaignDashboardTotalsReference totals = new CampaignDashboardTotalsReference(data.getGroupingKey(), data.getStack());
63+
Double value = percentageMap.getOrDefault(totals, 0D);
64+
value += data.getValueSum().doubleValue();
65+
percentageMap.put(totals, value);
66+
}
67+
campaignFormTotalsMap.put(campaignDashboardDiagramDto, percentageMap);
7168
}
72-
campaignFormTotalsMap.put(campaignDashboardDiagramDto, percentageMap);
7369
}
7470
});
7571
}
7672

73+
private void createCampaignDashboardDiagramDefinitionsMap() {
74+
if (!campaignDiagramDefinitionsMap.containsKey(campaign)) {
75+
final List<CampaignDashboardDiagramDto> campaignDashboardDiagramDtos = new ArrayList<>();
76+
final List<CampaignDashboardElement> campaignDashboardElements =
77+
FacadeProvider.getCampaignFacade().getCampaignDashboardElements(campaign.getUuid());
78+
final List<CampaignDiagramDefinitionDto> campaignDiagramDefinitions = FacadeProvider.getCampaignDiagramDefinitionFacade().getAll();
79+
80+
campaignDashboardElements.stream()
81+
.sorted(Comparator.comparingInt(CampaignDashboardElement::getOrder))
82+
.forEach(campaignDashboardElement -> {
83+
final Optional<CampaignDiagramDefinitionDto> first = campaignDiagramDefinitions.stream()
84+
.filter(
85+
campaignDiagramDefinitionDto -> campaignDiagramDefinitionDto.getDiagramId()
86+
.equals(campaignDashboardElement.getDiagramId()))
87+
.findFirst();
88+
if (first.isPresent()) {
89+
CampaignDiagramDefinitionDto campaignDiagramDefinitionDto = first.get();
90+
campaignDashboardDiagramDtos.add(new CampaignDashboardDiagramDto(campaignDashboardElement, campaignDiagramDefinitionDto));
91+
}
92+
});
93+
94+
campaignDiagramDefinitionsMap.put(campaign, campaignDashboardDiagramDtos);
95+
}
96+
}
97+
7798
public CampaignReferenceDto getLastStartedCampaign() {
7899
return FacadeProvider.getCampaignFacade().getLastStartedCampaign();
79100
}
@@ -117,4 +138,21 @@ public Map<CampaignDashboardDiagramDto, List<CampaignDiagramDataDto>> getCampaig
117138
public Map<CampaignDashboardDiagramDto, Map<CampaignDashboardTotalsReference, Double>> getCampaignFormTotalsMap() {
118139
return campaignFormTotalsMap;
119140
}
141+
142+
public List<String> getTabIds() {
143+
return campaignDiagramDefinitionsMap.get(campaign)
144+
.stream()
145+
.map(cdd -> cdd.getCampaignDashboardElement().getTabId())
146+
.distinct()
147+
.collect(Collectors.toList());
148+
}
149+
150+
public List<String> getSubTabIds(String tabId) {
151+
return campaignDiagramDefinitionsMap.get(campaign)
152+
.stream()
153+
.filter(cdd -> cdd.getCampaignDashboardElement().getTabId().equals(tabId))
154+
.map(cdd -> cdd.getCampaignDashboardElement().getSubTabId())
155+
.distinct()
156+
.collect(Collectors.toList());
157+
}
120158
}

sormas-ui/src/main/java/de/symeda/sormas/ui/dashboard/campaigns/CampaignDashboardFilterLayout.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public CampaignDashboardFilterLayout(CampaignDashboardView dashboardView, Campai
5151

5252
private void createCampaignFilter() {
5353
campaignFilter.setRequired(true);
54+
campaignFilter.setNullSelectionAllowed(false);
5455
campaignFilter.setCaption(I18nProperties.getCaption(Captions.Campaign));
5556
campaignFilter.setWidth(200, Unit.PIXELS);
5657
campaignFilter.setInputPrompt(I18nProperties.getString(Strings.promptCampaign));

sormas-ui/src/main/java/de/symeda/sormas/ui/dashboard/campaigns/CampaignDashboardView.java

Lines changed: 66 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package de.symeda.sormas.ui.dashboard.campaigns;
22

33
import java.util.ArrayList;
4-
import java.util.HashMap;
54
import java.util.List;
65
import java.util.Map;
76
import java.util.UUID;
@@ -12,6 +11,7 @@
1211
import com.vaadin.navigator.ViewChangeListener;
1312
import com.vaadin.server.Page;
1413
import com.vaadin.shared.ui.MarginInfo;
14+
import com.vaadin.ui.Component;
1515
import com.vaadin.ui.CssLayout;
1616
import com.vaadin.ui.JavaScript;
1717
import com.vaadin.ui.JavaScriptFunction;
@@ -24,6 +24,7 @@
2424
import de.symeda.sormas.api.campaign.diagram.CampaignDiagramDefinitionDto;
2525
import de.symeda.sormas.api.i18n.I18nProperties;
2626
import de.symeda.sormas.api.i18n.Strings;
27+
import de.symeda.sormas.ui.SubMenu;
2728
import de.symeda.sormas.ui.dashboard.AbstractDashboardView;
2829
import de.symeda.sormas.ui.dashboard.DashboardType;
2930
import de.symeda.sormas.ui.utils.CssStyles;
@@ -37,8 +38,10 @@ public class CampaignDashboardView extends AbstractDashboardView {
3738
protected CampaignDashboardFilterLayout filterLayout;
3839
protected CampaignDashboardDataProvider dataProvider;
3940

40-
private List<VerticalLayout> campaignDashboardDiagramComponents = new ArrayList<>();
41+
private List<VerticalLayout> campaignDashboardTabComponents = new ArrayList<>();
4142
private List<String> campaignDashboardDiagramStyles = new ArrayList<>();
43+
private Component currentSubTabsWrapper;
44+
private Component currentDiagramsWrapper;
4245

4346
public CampaignDashboardView() {
4447
super(VIEW_NAME);
@@ -67,13 +70,13 @@ public void refreshDashboard() {
6770

6871
final Page page = Page.getCurrent();
6972
cleanupDashboard(page);
70-
dataProvider.refreshData();
73+
dataProvider.refreshDashboardData();
7174

7275
final VerticalLayout tabLayout = new VerticalLayout();
7376
tabLayout.setSizeFull();
7477
tabLayout.setMargin(new MarginInfo(false, false, false, false));
7578
tabLayout.setSpacing(false);
76-
campaignDashboardDiagramComponents.add(tabLayout);
79+
campaignDashboardTabComponents.add(tabLayout);
7780
dashboardLayout.addComponent(tabLayout);
7881
dashboardLayout.setExpandRatio(tabLayout, 1);
7982

@@ -84,40 +87,79 @@ public void refreshDashboard() {
8487
tabLayout.addComponent(tabSwitcherLayout);
8588
tabLayout.setExpandRatio(tabSwitcherLayout, 0);
8689

87-
final Map<String, Map<CampaignDashboardDiagramDto, List<CampaignDiagramDataDto>>> campaignFormDataTabMap =
88-
groupCampaignFormDataByTab(dataProvider.getCampaignFormDataMap());
89-
final List<String> tabs = new ArrayList<>(campaignFormDataTabMap.keySet());
90+
final List<String> tabs = new ArrayList<>(dataProvider.getTabIds());
9091
tabs.forEach(tabId -> {
9192
tabSwitcher.addItem(tabId);
9293
tabSwitcher.setItemCaption(tabId, tabId);
9394
});
9495
if (!(tabs.size() > 1)) {
9596
tabSwitcherLayout.setVisible(false);
9697
}
98+
tabSwitcher.setValue(tabs.isEmpty() ? StringUtils.EMPTY : tabs.get(0));
99+
97100
CssStyles.style(tabSwitcher, CssStyles.FORCE_CAPTION, ValoTheme.OPTIONGROUP_HORIZONTAL, CssStyles.OPTIONGROUP_HORIZONTAL_PRIMARY);
98101

102+
final VerticalLayout subTabLayout = new VerticalLayout();
103+
subTabLayout.setSizeFull();
104+
subTabLayout.setMargin(new MarginInfo(false, false, false, false));
105+
subTabLayout.setSpacing(false);
106+
campaignDashboardTabComponents.add(subTabLayout);
107+
tabLayout.addComponent(subTabLayout);
108+
tabLayout.setExpandRatio(subTabLayout, 1);
109+
99110
tabSwitcher.addValueChangeListener(e -> {
100-
String tabId = (String) e.getProperty().getValue();
101-
tabLayout.iterator().forEachRemaining(component -> {
102-
if (tabId.equals(component.getId())) {
103-
component.setVisible(true);
104-
} else if (component.getId() != null) {
105-
component.setVisible(false);
106-
}
107-
});
111+
final String tabId = (String) e.getProperty().getValue();
112+
subTabLayout.removeComponent(currentDiagramsWrapper);
113+
subTabLayout.removeComponent(currentSubTabsWrapper);
114+
refreshSubTabs(page, tabId, subTabLayout);
108115
});
116+
refreshSubTabs(page, (String) tabSwitcher.getValue(), subTabLayout);
117+
}
118+
119+
@SuppressWarnings("deprecation")
120+
private void refreshSubTabs(Page page, String tabId, VerticalLayout subTabLayout) {
121+
122+
final List<String> subTabs = new ArrayList<>(dataProvider.getSubTabIds(tabId));
123+
final SubMenu subTabSwitcher = new SubMenu();
124+
125+
final VerticalLayout subTabSwitcherLayout = new VerticalLayout(subTabSwitcher);
126+
subTabSwitcherLayout.setMargin(new MarginInfo(false, false, false, true));
127+
subTabSwitcherLayout.setSpacing(false);
128+
subTabSwitcherLayout.setId("subTabsOf" + tabId);
129+
currentSubTabsWrapper = subTabSwitcherLayout;
130+
subTabLayout.addComponent(subTabSwitcherLayout);
131+
subTabLayout.setExpandRatio(subTabSwitcherLayout, 0);
132+
133+
subTabs.forEach(subTabId -> subTabSwitcher.addView(subTabId, subTabId, (e) -> {
134+
subTabLayout.removeComponent(currentDiagramsWrapper);
135+
refreshDiagrams(page, subTabLayout, tabId, subTabId);
136+
}));
137+
if (!(subTabs.size() > 1)) {
138+
subTabSwitcherLayout.setVisible(false);
139+
}
140+
String firstSubTab = subTabs.isEmpty() ? StringUtils.EMPTY : subTabs.get(0);
141+
subTabSwitcher.setActiveView(firstSubTab);
142+
143+
refreshDiagrams(page, subTabLayout, tabId, firstSubTab);
144+
}
109145

146+
private void refreshDiagrams(Page page, VerticalLayout layout, String tabId, String subTabId) {
110147
final Page.Styles styles = page.getStyles();
111148

112-
campaignFormDataTabMap.forEach((tabId, campaignFormDataMap) -> {
149+
dataProvider.refreshDiagramsData(tabId, subTabId);
113150

151+
Map<CampaignDashboardDiagramDto, List<CampaignDiagramDataDto>> campaignFormDataMap = dataProvider.getCampaignFormDataMap();
152+
153+
if (campaignFormDataMap != null && !campaignFormDataMap.isEmpty()) {
114154
final List<CampaignDashboardElement> dashboardElements =
115155
campaignFormDataMap.keySet().stream().map(CampaignDashboardDiagramDto::getCampaignDashboardElement).collect(Collectors.toList());
156+
116157
final GridTemplateAreaCreator gridTemplateAreaCreator = new GridTemplateAreaCreator(dashboardElements);
117158

118159
final VerticalLayout diagramsWrapper = new VerticalLayout();
119160
diagramsWrapper.setMargin(new MarginInfo(false, true, false, true));
120-
diagramsWrapper.setId(tabId);
161+
diagramsWrapper.setId(tabId + "_" + subTabId);
162+
currentDiagramsWrapper = diagramsWrapper;
121163

122164
diagramsWrapper.setWidth(
123165
dashboardElements.size() == 1 && gridTemplateAreaCreator.getGridColumns() == 1 ? gridTemplateAreaCreator.getWidthsSum() : 100,
@@ -126,7 +168,7 @@ public void refreshDashboard() {
126168

127169
final CssLayout diagramsLayout = new CssLayout();
128170
diagramsLayout.setSizeFull();
129-
final String gridCssClass = tabId.replaceAll("[^a-zA-Z]+", "") + generateRandomString() + GRID_CONTAINER;
171+
final String gridCssClass = (tabId + subTabId).replaceAll("[^a-zA-Z]+", "") + generateRandomString() + GRID_CONTAINER;
130172

131173
styles.add(
132174
createDiagramGridStyle(
@@ -161,18 +203,16 @@ public void refreshDashboard() {
161203
});
162204
diagramsWrapper.addComponent(diagramsLayout);
163205

164-
diagramsWrapper.setVisible(false);
165-
tabLayout.addComponent(diagramsWrapper);
166-
tabLayout.setExpandRatio(diagramsWrapper, 1);
167-
});
168-
169-
tabSwitcher.setValue(tabs.isEmpty() ? StringUtils.EMPTY : tabs.get(0));
206+
diagramsWrapper.setVisible(true);
207+
layout.addComponent(diagramsWrapper);
208+
layout.setExpandRatio(diagramsWrapper, 1);
209+
}
170210
}
171211

172212
private void cleanupDashboard(Page page) {
173-
campaignDashboardDiagramComponents
213+
campaignDashboardTabComponents
174214
.forEach(campaignDashboardDiagramComponents -> dashboardLayout.removeComponent(campaignDashboardDiagramComponents));
175-
campaignDashboardDiagramComponents.clear();
215+
campaignDashboardTabComponents.clear();
176216
campaignDashboardDiagramStyles.forEach(s -> page.getJavaScript().execute(removeStyles(s)));
177217
campaignDashboardDiagramStyles.clear();
178218
}
@@ -199,21 +239,4 @@ private String removeStyles(String styleInnerText) {
199239
+ "if (diagramStyles[i].innerText.startsWith(\"" + styleInnerText
200240
+ "\" )) { diagramStyles[i].parentNode.removeChild(diagramStyles[i]);}}";
201241
}
202-
203-
private Map<String, Map<CampaignDashboardDiagramDto, List<CampaignDiagramDataDto>>> groupCampaignFormDataByTab(
204-
Map<CampaignDashboardDiagramDto, List<CampaignDiagramDataDto>> campaignFormDataMap) {
205-
final Map<String, Map<CampaignDashboardDiagramDto, List<CampaignDiagramDataDto>>> campaignFormDataTabMap = new HashMap<>();
206-
207-
campaignFormDataMap.forEach((campaignDashboardDiagramDto, campaignDiagramDataDtos) -> {
208-
final String tabId = campaignDashboardDiagramDto.getCampaignDashboardElement().getTabId();
209-
if (campaignFormDataTabMap.containsKey(tabId)) {
210-
campaignFormDataTabMap.get(tabId).put(campaignDashboardDiagramDto, campaignDiagramDataDtos);
211-
} else {
212-
final Map<CampaignDashboardDiagramDto, List<CampaignDiagramDataDto>> dashboardDiagramDtoListHashMap = new HashMap<>();
213-
dashboardDiagramDtoListHashMap.put(campaignDashboardDiagramDto, campaignDiagramDataDtos);
214-
campaignFormDataTabMap.put(tabId, dashboardDiagramDtoListHashMap);
215-
}
216-
});
217-
return campaignFormDataTabMap;
218-
}
219242
}

0 commit comments

Comments
 (0)