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

Handle articles in multiple sections #552

Merged
merged 1 commit into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions app/components/Article/KeepGoing/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {useLocation} from 'react-router-dom'
import Button from '~/components/Button'
import ListTable from '~/components/Table'
import {ArrowRight} from '~/components/icons-generated'
Expand All @@ -24,7 +25,11 @@ const NextArticle = ({section, next, first}: NextArticleProps) =>
</div>
<div className={`${styles.container} flex-container bordered ${styles.flex_dynamic}`}>
<div className="vertically-centered white default-bold">{next.title}</div>
<Button action={questionUrl(next)} className="vertically-centered primary-alt">
<Button
action={questionUrl(next)}
className="vertically-centered primary-alt"
props={{state: {section: section?.pageid}}}
>
{first ? 'Start' : 'Next'}
<ArrowRight />
</Button>
Expand All @@ -33,9 +38,10 @@ const NextArticle = ({section, next, first}: NextArticleProps) =>
)

export const KeepGoing = ({pageid, relatedQuestions}: Question) => {
const location = useLocation()
const {findSection, getArticle, getNext} = useToC()
const section = findSection(pageid)
const next = getNext(pageid)
const section = findSection(location?.state?.section || pageid)
const next = getNext(pageid, section?.pageid)
const hasRelated = relatedQuestions && relatedQuestions.length > 0
const skipNext = nonContinueSections.includes(section?.pageid || '')

Expand Down
21 changes: 18 additions & 3 deletions app/components/ArticlesDropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@ export const ArticlesDropdown = ({toc, categories}: ArticlesDropdownProps) => {
const hide = () => setShown(true)
useEffect(() => setShown(false), [shown])
const mobile = useIsMobile()
const Link = ({to, text, className}: {to: string; text: string; className?: string}) => (
const Link = ({
to,
text,
pageid,
className,
}: {
to: string
text: string
pageid?: string
className?: string
}) => (
<div className={'articles-dropdown-entry ' + (className || '')}>
<LinkElem to={to} onClick={hide}>
<LinkElem to={to} onClick={hide} state={{section: pageid}}>
{text}
</LinkElem>
</div>
Expand All @@ -44,7 +54,12 @@ export const ArticlesDropdown = ({toc, categories}: ArticlesDropdownProps) => {
{toc
.filter((item) => item.category === category)
.map((item: TOCItem) => (
<Link key={`${item.pageid}-${item.title}`} to={questionUrl(item)} text={item.title} />
<Link
key={`${item.pageid}-${item.title}`}
to={questionUrl(item)}
text={item.title}
pageid={item.pageid}
/>
))}
</div>
)
Expand Down
8 changes: 7 additions & 1 deletion app/components/ArticlesNav/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ const Title = ({article, path, current}: Article) => {

return (
<summary className={'articles-title ' + classes}>
{!article.hasText ? article.title : <Link to={questionUrl(article)}>{article.title}</Link>}
{!article.hasText ? (
article.title
) : (
<Link to={questionUrl(article)} state={{section: path && path[0]}}>
{article.title}
</Link>
)}
{!isHeader && <DropdownIcon article={article} path={path} />}
</summary>
)
Expand Down
28 changes: 23 additions & 5 deletions app/hooks/useToC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,29 @@ const useToC = () => {
}

const findSection = (pageid: string): TOCItem | undefined => {
return (toc || []).filter(checkPath(pageid))[0]
const checker = checkPath(pageid)
// Articles can be in multiple sections, or even be sections. It's assumed here that
// the highest level usage should be used, so assuming article "ABC", with the following
// paths:
// * ["123", "432", "ABC"]
// * ["123", "ABC"]
// * ["324", "ABC"]
// * ["ABC"]
// Then that the shorter the path, the better
return (toc || [])
.filter(checker)
.sort((a, b) => (checker(a)?.length || 20) - (checker(b)?.length || 20))[0]
}

const getPath = (pageid: string) => {
const getPath = (pageid: string, sectionId?: string) => {
if (!toc || toc.length === 0) return undefined
return toc.map(checkPath(pageid)).filter(identity)[0]
const paths = toc.map(checkPath(pageid)).filter(identity)

if (sectionId) return paths.filter((p) => p && p[0] === sectionId)[0]
return paths[0]
}

const getNext = (pageid: string): TOCItem | undefined => {
const getNext = (pageid: string, sectionId?: string): TOCItem | undefined => {
type NextItem = {
current?: string
next?: TOCItem
Expand All @@ -47,7 +61,11 @@ const useToC = () => {
return {current: previous}
}

return toc?.map((section) => findNext('', section).next).filter(identity)[0]
// Assume that next articles must always be in the same section
return toc
?.filter(({pageid}) => pageid === sectionId)
.map((section) => findNext('', section).next)
.filter(identity)[0]
}

return {
Expand Down
5 changes: 3 additions & 2 deletions app/routes/questions.$questionId.$.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default function RenderArticle() {
const pageid = params.questionId ?? '😱'
const {data, tags} = useLoaderData<typeof loader>()
const {findSection, getArticle, getPath} = useToC()
const section = findSection(pageid)
const section = findSection(location?.state?.section || pageid)

useEffect(() => {
const getGlossary = async () => {
Expand Down Expand Up @@ -119,11 +119,12 @@ export default function RenderArticle() {
<ChevronRight className="dropdown-icon active" />
</Button>
)}

{section && (
<ArticlesNav
current={pageid}
article={section}
path={getPath(pageid)}
path={getPath(pageid, section?.pageid)}
className={!showNav ? 'desktop-only bordered' : ''}
/>
)}
Expand Down
Loading