Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Topics tab refactoring #4826

Merged
merged 11 commits into from
Jan 3, 2025
13 changes: 11 additions & 2 deletions server/routes/dev_place/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions server/routes/dev_place/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down
168 changes: 82 additions & 86 deletions static/js/place/dev_place_main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div className="item-list-item">
<a
href={createHref(category, forceDevPlaces, place)}
className={`item-list-text + ${
selectedCategory === category ? " selected" : ""
}`}
>
{category}
</a>
</div>
);
};

/**
* Component that renders the topic navigation tabs.
* Shows tabs for Overview and different categories like Economics, Health, etc.
Expand All @@ -194,103 +244,34 @@ const PlaceHeader = (props: {
* @returns Navigation component with topic tabs
*/
const PlaceTopicTabs = ({
topics,
forceDevPlaces,
category,
place,
}: {
topics: string[];
forceDevPlaces: boolean;
category: string;
place: NamedTypedPlace;
}): React.JSX.Element => {
if (!topics || topics.length == 0) {
return <></>;
}

return (
<div className="explore-topics-box">
<span className="explore-relevant-topics">Relevant topics</span>
<div className="item-list-container">
<div className="item-list-inner">
<div className="item-list-item">
<a
className={`item-list-text ${
category === "Overview" ? "selected" : ""
}`}
href={`/place/${place.dcid}${
forceDevPlaces ? "?force_dev_places=true" : ""
}`}
>
Overview
</a>
</div>
<div className="item-list-item">
<a
className={`item-list-text ${
category === "Economics" ? "selected" : ""
}`}
href={`/place/${place.dcid}?category=Economics${
forceDevPlaces ? "&force_dev_places=true" : ""
}`}
>
Economics
</a>
</div>
<div className="item-list-item">
<a
className={`item-list-text ${
category === "Health" ? "selected" : ""
}`}
href={`/place/${place.dcid}?category=Health${
forceDevPlaces ? "&force_dev_places=true" : ""
}`}
>
Health
</a>
</div>
<div className="item-list-item">
<a
className={`item-list-text ${
category === "Equity" ? "selected" : ""
}`}
href={`/place/${place.dcid}?category=Equity${
forceDevPlaces ? "&force_dev_places=true" : ""
}`}
>
Equity
</a>
</div>
<div className="item-list-item">
<a
className={`item-list-text ${
category === "Demographics" ? "selected" : ""
}`}
href={`/place/${place.dcid}?category=Demographics${
forceDevPlaces ? "&force_dev_places=true" : ""
}`}
>
Demographics
</a>
</div>
<div className="item-list-item">
<a
className={`item-list-text ${
category === "Environment" ? "selected" : ""
}`}
href={`/place/${place.dcid}?category=Environment${
forceDevPlaces ? "&force_dev_places=true" : ""
}`}
>
Environment
</a>
</div>
<div className="item-list-item">
<a
className={`item-list-text ${
category === "Energy" ? "selected" : ""
}`}
href={`/place/${place.dcid}?category=Energy${
forceDevPlaces ? "&force_dev_places=true" : ""
}`}
>
Energy
</a>
</div>
{topics.map((topic) => (
<TopicItem
key={topic}
category={topic}
selectedCategory={category}
forceDevPlaces={forceDevPlaces}
place={place}
/>
))}
</div>
</div>
</div>
Expand Down Expand Up @@ -540,6 +521,7 @@ export const DevPlaceMain = (): React.JSX.Element => {
const [childPlaces, setChildPlaces] = useState<NamedTypedPlace[]>([]);
const [parentPlaces, setParentPlaces] = useState<NamedTypedPlace[]>([]);
const [pageConfig, setPageConfig] = useState<SubjectPageConfig>();
const [categories, setCategories] = useState<string[]>();

const urlParams = new URLSearchParams(window.location.search);
const category = urlParams.get("category") || "Overview";
Expand Down Expand Up @@ -586,16 +568,29 @@ export const DevPlaceMain = (): React.JSX.Element => {

setPlaceChartsApiResponse(placeChartsApiResponse);
setRelatedPlacesApiResponse(relatedPlacesApiResponse);
const pageConfig = placeChartsApiResponsesToPageConfig(
const config = placeChartsApiResponsesToPageConfig(
placeChartsApiResponse
);
setChildPlaceType(relatedPlacesApiResponse.childPlaceType);
setChildPlaces(relatedPlacesApiResponse.childPlaces);
setParentPlaces(relatedPlacesApiResponse.parentPlaces);
setPageConfig(pageConfig);
setPageConfig(config);
})();
}, [place]);

useEffect(() => {
if (placeChartsApiResponse && placeChartsApiResponse.charts) {
// TODO(gmechali): Refactor this to use the translations correctly.
// Move overview to be added in the response with translations. Use the
// translation in the tabs, but the english version in the URL.
setCategories(
["Overview"].concat(
Object.values(placeChartsApiResponse.translatedCategoryStrings)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this categories list should store both the english & translated values (one to use on the page text, and one to use in the URL param for the place page)

Copy link
Contributor

@dwnoble dwnoble Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also- we should add "Overview": "_translated overview value_" to the translatedCategoryStrings entry in the API response.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I see. Are the translation implemented yet? I tried using it with different HL params and it didnt do anything. I assume we'll need a bit more refactoring here, for example the overview topic will need a translation too, so it should come from the backend probably.
I added a todo to figure this part out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The translations are implemented, but i think there's some extra wiring we need to do to get the frontend to pass the language to the API.

FR example in autopush: https://autopush.datacommons.org/api/dev-place/charts/country/LVA?category=Overview&hl=fr

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack will see what's up with those in follow up.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good!

)
);
}
}, [placeChartsApiResponse, setPlaceChartsApiResponse, setCategories]);

if (!place) {
return <div>Loading...</div>;
}
Expand All @@ -607,6 +602,7 @@ export const DevPlaceMain = (): React.JSX.Element => {
placeSubheader={placeSubheader}
/>
<PlaceTopicTabs
topics={categories}
category={category}
place={place}
forceDevPlaces={forceDevPlaces}
Expand Down
Loading