diff --git a/server/routes/dev_place/api.py b/server/routes/dev_place/api.py index 4d6ad68bcc..39c097c9e5 100644 --- a/server/routes/dev_place/api.py +++ b/server/routes/dev_place/api.py @@ -90,8 +90,9 @@ def place_charts(place_dcid: str): full_chart_config = copy.deepcopy(current_app.config['CHART_CONFIG']) # Filter chart config by category + overview_chart_config = [c for c in full_chart_config if c.get("isOverview")] if place_category == OVERVIEW_CATEGORY: - chart_config = [c for c in full_chart_config if c.get("isOverview")] + chart_config = overview_chart_config else: chart_config = [ c for c in full_chart_config if c["category"] == place_category @@ -103,6 +104,14 @@ def place_charts(place_dcid: str): place_dcid=place_dcid, child_place_type=child_place_type) + # Always execute the call for the overview category to fetch the valid categories. + filtered_chart_config_for_category = ( + filtered_chart_config if place_category == OVERVIEW_CATEGORY else + place_utils.filter_chart_config_by_place_dcid( + chart_config=overview_chart_config, + place_dcid=place_dcid, + child_place_type=child_place_type)) + # Translate chart config titles translated_chart_config = place_utils.translate_chart_config( filtered_chart_config) @@ -113,7 +122,7 @@ def place_charts(place_dcid: str): # Translate category strings translated_category_strings = place_utils.get_translated_category_strings( - filtered_chart_config) + filtered_chart_config_for_category) response = PlaceChartsApiResponse( charts=charts, diff --git a/server/routes/dev_place/utils.py b/server/routes/dev_place/utils.py index daebf4a69b..0767d263b8 100644 --- a/server/routes/dev_place/utils.py +++ b/server/routes/dev_place/utils.py @@ -20,7 +20,9 @@ from flask_babel import gettext from server.lib import fetch +from server.lib.cache import cache from server.lib.i18n import DEFAULT_LOCALE +from server.routes import TIMEOUT from server.routes.dev_place.types import Chart from server.routes.dev_place.types import Place import server.routes.shared_api.place as place_api @@ -128,6 +130,7 @@ def get_place_type_with_parent_places_links(dcid: str) -> str: return '' +@cache.memoize(timeout=TIMEOUT) def filter_chart_config_by_place_dcid(chart_config: List[Dict], place_dcid: str, child_place_type=str): diff --git a/static/js/place/dev_place_main.tsx b/static/js/place/dev_place_main.tsx index e549010302..fe010bcdb5 100644 --- a/static/js/place/dev_place_main.tsx +++ b/static/js/place/dev_place_main.tsx @@ -184,6 +184,56 @@ const PlaceHeader = (props: { ); }; +/** + * Component that renders the individual topic navigation buttons. + * Shows buttons for the topics created and highlights the currently selected category. + * + * @param props.category The category for the current button + * @param props.selectedCategory The currently selected category + * @param props.forceDevPlaces Whether the flag to force dev places should be propagated. + * @param props.place The place object containing the DCID for generating URLs + * @returns Button component for the current topic + */ +const TopicItem = (props: { + category: string; + selectedCategory: string; + forceDevPlaces: boolean; + place: NamedTypedPlace; +}): React.JSX.Element => { + const { category, selectedCategory, forceDevPlaces, place } = props; + + const createHref = ( + category: string, + forceDevPlaces: boolean, + place: NamedTypedPlace + ): string => { + const href = `/place/${place.dcid}`; + const params = new URLSearchParams(); + const isOverview = category === "Overview"; + + if (!isOverview) { + params.set("category", category); + } + if (forceDevPlaces) { + params.set("force_dev_places", "true"); + } + return params.size > 0 ? `${href}?${params.toString()}` : href; + }; + + return ( +