-
Notifications
You must be signed in to change notification settings - Fork 89
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
Topics tab refactoring #4826
Changes from 9 commits
b2305dc
5f45bbe
68dd718
c840acc
08bce04
6b4ad85
12cb9b9
801e59a
41dd469
2dbfa6b
6015181
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -184,6 +184,61 @@ 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 isOverview = category === "Overview"; | ||
|
||
let href = `/place/${place.dcid}`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using URLSearchParams might make this more clear. Something like:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done - definitely cleans it up a bit, thanks! |
||
if (!isOverview || forceDevPlaces) { | ||
href += "?"; | ||
} | ||
if (!isOverview) { | ||
href += `category=${category}`; | ||
} | ||
if (forceDevPlaces && !isOverview) { | ||
href += "&"; | ||
} | ||
if (forceDevPlaces) { | ||
href += "force_dev_places=true"; | ||
} | ||
return 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. | ||
|
@@ -194,103 +249,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> | ||
|
@@ -540,6 +526,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"; | ||
|
@@ -586,16 +573,30 @@ 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) { | ||
const categories = new Set<string>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this categories set used somewhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh i was using that before but then switched to using the translatedCategories directly, so I think we're good now. Removed. |
||
placeChartsApiResponse.charts.forEach((chart) => { | ||
categories.add(chart.category); | ||
}); | ||
setCategories( | ||
["Overview"].concat( | ||
Object.values(placeChartsApiResponse.translatedCategoryStrings) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also- we should add There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ack will see what's up with those in follow up. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds good! |
||
) | ||
); | ||
} | ||
}, [placeChartsApiResponse, setPlaceChartsApiResponse, setCategories]); | ||
|
||
if (!place) { | ||
return <div>Loading...</div>; | ||
} | ||
|
@@ -607,6 +608,7 @@ export const DevPlaceMain = (): React.JSX.Element => { | |
placeSubheader={placeSubheader} | ||
/> | ||
<PlaceTopicTabs | ||
topics={categories} | ||
category={category} | ||
place={place} | ||
forceDevPlaces={forceDevPlaces} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs to be @cache.memoize() to include the arguments in the cache key: https://flask-caching.readthedocs.io/en/latest/#memoization
Also-you can enable caching locally for testing by setting
USE_MEMCACHE = True
hereThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and tested cache locally, confirming it's very fast now!