CommitteeDecisionFlowPageModContentFactoryImpl.java

  1. /*
  2.  * Copyright 2010-2025 James Pether Sörling
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *   http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  *
  16.  *  $Id$
  17.  *  $HeadURL$
  18. */
  19. package com.hack23.cia.web.impl.ui.application.views.user.committee.pagemode;

  20. import java.time.LocalDate;
  21. import java.time.ZoneOffset;
  22. import java.util.Collections;
  23. import java.util.Comparator;
  24. import java.util.List;
  25. import java.util.Locale;
  26. import java.util.Map;
  27. import java.util.stream.Collectors;
  28. import java.util.stream.IntStream;

  29. import org.springframework.beans.factory.annotation.Autowired;
  30. import org.springframework.security.access.annotation.Secured;
  31. import org.springframework.stereotype.Component;

  32. import com.hack23.cia.model.internal.application.data.committee.impl.ViewRiksdagenCommittee;
  33. import com.hack23.cia.model.internal.application.system.impl.ApplicationEventGroup;
  34. import com.hack23.cia.web.impl.ui.application.action.ViewAction;
  35. import com.hack23.cia.web.impl.ui.application.views.common.chartfactory.api.DecisionFlowChartManager;
  36. import com.hack23.cia.web.impl.ui.application.views.common.menufactory.api.pagecommands.PageCommandCommitteeConstants;
  37. import com.hack23.cia.web.impl.ui.application.views.common.pagemode.CardInfoRowUtil;
  38. import com.hack23.cia.web.impl.ui.application.views.common.sizing.ContentRatio;
  39. import com.hack23.cia.web.impl.ui.application.views.pageclicklistener.DecisionFlowValueChangeListener;
  40. import com.hack23.cia.web.widgets.charts.SankeyChart;
  41. import com.vaadin.ui.ComboBox;
  42. import com.vaadin.ui.Layout;
  43. import com.vaadin.ui.MenuBar;
  44. import com.vaadin.ui.Panel;
  45. import com.vaadin.ui.TextArea;
  46. import com.vaadin.ui.VerticalLayout;

  47. /**
  48.  * The Class ParliamentDecisionFlowPageModContentFactoryImpl.
  49.  */
  50. @Component
  51. public final class CommitteeDecisionFlowPageModContentFactoryImpl extends AbstractCommitteePageModContentFactoryImpl {

  52.     /** The Constant DEFAULT_YEAR. */
  53.     private static final String DEFAULT_YEAR = "2023/24";

  54.     /** The decision flow chart manager. */
  55.     @Autowired
  56.     private DecisionFlowChartManager decisionFlowChartManager;

  57.     /**
  58.      * Creates the content.
  59.      *
  60.      * @param parameters the parameters
  61.      * @param menuBar the menu bar
  62.      * @param panel the panel
  63.      * @return the layout
  64.      */
  65.     @Secured({ "ROLE_ANONYMOUS", "ROLE_USER", "ROLE_ADMIN" })
  66.     @Override
  67.     public Layout createContent(final String parameters, final MenuBar menuBar, final Panel panel) {
  68.         final VerticalLayout panelContent = createPanelContent();
  69.         final String pageId = getPageId(parameters);
  70.         final ViewRiksdagenCommittee committee = getItem(parameters);

  71.         setupMenuAndHeader(menuBar, panel, panelContent, pageId, committee);
  72.         final String selectedYear = extractSelectedYear(parameters);
  73.         final Map<String, List<ViewRiksdagenCommittee>> committeeMap = loadCommitteeMap();

  74.         addYearSelector(panelContent, selectedYear, pageId);
  75.         addDecisionFlowChart(panelContent, committee, committeeMap, selectedYear);
  76.         addDecisionSummary(panelContent, committee, selectedYear);

  77.         recordPageVisit(parameters, pageId);

  78.         return panelContent;
  79.     }

  80.     /**
  81.      * Creates list of available years for selection.
  82.      * Goes from 2010/11 up to (currentYear+1)/(currentYear+2).
  83.      *
  84.      * @return Unmodifiable list of year strings in format "YYYY/YY"
  85.      */
  86.     private static List<String> createAvailableYears() {
  87.         final int currentYear = LocalDate.now((ZoneOffset.UTC)).getYear();
  88.         return IntStream.rangeClosed(2010, currentYear + 1)
  89.             .mapToObj(year -> String.format(Locale.ENGLISH,"%d/%02d", year, (year + 1) % 100))
  90.             .sorted(Comparator.reverseOrder()) // Most recent years first
  91.             .collect(Collectors.collectingAndThen(
  92.                 Collectors.toList(),
  93.                 Collections::unmodifiableList
  94.             ));
  95.     }

  96.     /**
  97.      * Setup menu and header.
  98.      *
  99.      * @param menuBar the menu bar
  100.      * @param panel the panel
  101.      * @param panelContent the panel content
  102.      * @param pageId the page id
  103.      * @param committee the committee
  104.      */
  105.     private void setupMenuAndHeader(final MenuBar menuBar, final Panel panel, final VerticalLayout panelContent,
  106.             final String pageId, final ViewRiksdagenCommittee committee) {
  107.         getCommitteeMenuItemFactory().createCommitteeeMenuBar(menuBar, pageId);
  108.         CardInfoRowUtil.createPageHeader(panel, panelContent,
  109.             CommitteeViewConstants.DF_TITLE_HEADER + committee.getEmbeddedId().getDetail(),
  110.             CommitteeViewConstants.DF_TITLE,
  111.             CommitteeViewConstants.DF_DESCRIPTION
  112.         );
  113.     }

  114.     /**
  115.      * Extract selected year.
  116.      *
  117.      * @param parameters the parameters
  118.      * @return the string
  119.      */
  120.     private String extractSelectedYear(final String parameters) {
  121.         if (parameters != null && parameters.contains("[") && parameters.contains("]")) {
  122.             return parameters.substring(
  123.                 parameters.indexOf('[') + 1,
  124.                 parameters.lastIndexOf(']')
  125.             );
  126.         }
  127.         return DEFAULT_YEAR;
  128.     }

  129.     /**
  130.      * Load committee map.
  131.      *
  132.      * @return the map
  133.      */
  134.     private Map<String, List<ViewRiksdagenCommittee>> loadCommitteeMap() {
  135.         return getApplicationManager()
  136.             .getDataContainer(ViewRiksdagenCommittee.class)
  137.             .getAll()
  138.             .stream()
  139.             .collect(Collectors.groupingBy(
  140.                 committee -> committee.getEmbeddedId().getOrgCode().toUpperCase(Locale.ENGLISH)
  141.             ));
  142.     }

  143.     /**
  144.      * Adds the year selector.
  145.      *
  146.      * @param panelContent the panel content
  147.      * @param selectedYear the selected year
  148.      * @param pageId the page id
  149.      */
  150.     private void addYearSelector(final VerticalLayout panelContent, final String selectedYear, final String pageId) {
  151.         final ComboBox<String> yearSelector = new ComboBox<>(CommitteeViewConstants.DF_YEAR_SELECTOR, createAvailableYears());
  152.         yearSelector.setWidth("200px");
  153.         yearSelector.setEmptySelectionAllowed(false);
  154.         yearSelector.setSelectedItem(selectedYear);
  155.         yearSelector.addValueChangeListener(new DecisionFlowValueChangeListener(NAME, pageId));

  156.         panelContent.addComponent(yearSelector);
  157.         panelContent.setExpandRatio(yearSelector, ContentRatio.SMALL2);
  158.     }

  159.     /**
  160.      * Adds the decision flow chart.
  161.      *
  162.      * @param panelContent the panel content
  163.      * @param committee the committee
  164.      * @param committeeMap the committee map
  165.      * @param selectedYear the selected year
  166.      */
  167.     private void addDecisionFlowChart(final VerticalLayout panelContent, final ViewRiksdagenCommittee committee,
  168.             final Map<String, List<ViewRiksdagenCommittee>> committeeMap, final String selectedYear) {
  169.         final SankeyChart chart = decisionFlowChartManager.createCommitteeDecisionFlow(
  170.             committee, committeeMap, selectedYear
  171.         );
  172.         chart.setWidth("100%");

  173.         panelContent.addComponent(chart);
  174.         panelContent.setExpandRatio(chart, ContentRatio.LARGE);
  175.     }

  176.     /**
  177.      * Adds the decision summary.
  178.      *
  179.      * @param panelContent the panel content
  180.      * @param committee the committee
  181.      * @param selectedYear the selected year
  182.      */
  183.     private void addDecisionSummary(final VerticalLayout panelContent,
  184.             final ViewRiksdagenCommittee committee, final String selectedYear) {
  185.         final TextArea summaryArea = decisionFlowChartManager.createCommitteeeDecisionSummary(
  186.             committee, selectedYear
  187.         );
  188.         summaryArea.setSizeFull();
  189.         summaryArea.setReadOnly(true);

  190.         panelContent.addComponent(summaryArea);
  191.         panelContent.setExpandRatio(summaryArea, ContentRatio.SMALL_GRID);
  192.     }

  193.     /**
  194.      * Record page visit.
  195.      *
  196.      * @param parameters the parameters
  197.      * @param pageId the page id
  198.      */
  199.     private void recordPageVisit(final String parameters, final String pageId) {
  200.         getPageActionEventHelper().createPageEvent(
  201.             ViewAction.VISIT_COMMITTEE_VIEW,
  202.             ApplicationEventGroup.USER,
  203.             NAME,
  204.             parameters,
  205.             pageId
  206.         );
  207.     }

  208.     /**
  209.      * Matches.
  210.      *
  211.      * @param page the page
  212.      * @param parameters the parameters
  213.      * @return true, if successful
  214.      */
  215.     @Override
  216.     public boolean matches(final String page, final String parameters) {
  217.         return PageCommandCommitteeConstants.COMMAND_CHARTS_DECISION_FLOW.matches(page, parameters);
  218.     }
  219. }