Skip to content

Commit 5dbd8b5

Browse files
rseseCopilot
andauthored
Journey tracks for journey landing pages (#57722)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 1f0df74 commit 5dbd8b5

File tree

22 files changed

+887
-101
lines changed

22 files changed

+887
-101
lines changed

content/enterprise-onboarding/index.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,33 @@ featuredLinks:
1313
- '/enterprise-onboarding/github-actions-for-your-enterprise'
1414
- '/enterprise-onboarding/feature-enhancements'
1515
layout: product-landing
16+
journeyTracks:
17+
- id: 'getting_started'
18+
title: 'Getting started with your enterprise'
19+
description: 'Learn how to start a trial of {% data variables.product.prodname_enterprise %}, and about enterprise billing and migrations.'
20+
guides:
21+
- '/enterprise-onboarding/getting-started-with-your-enterprise/setting-up-a-trial-of-github-enterprise'
22+
- '/enterprise-onboarding/getting-started-with-your-enterprise/ending-a-trial-of-github-enterprise'
23+
- '/enterprise-onboarding/getting-started-with-your-enterprise/about-enterprise-billing'
24+
- '/enterprise-onboarding/getting-started-with-your-enterprise/about-migrating-to-github-enterprise-cloud'
25+
- '/enterprise-onboarding/getting-started-with-your-enterprise/securing-your-enterprise-with-managed-users'
26+
- '/enterprise-onboarding/getting-started-with-your-enterprise/securing-enterprise-resources-with-single-sign-on'
27+
- id: 'organizations_and_teams'
28+
title: 'Setting up organizations and teams in your enterprise'
29+
description: 'Learn how to add and manage organizations and teams in your enterprise.'
30+
guides:
31+
- '/enterprise-onboarding/setting-up-organizations-and-teams/setting-up-an-organization'
32+
- '/enterprise-onboarding/setting-up-organizations-and-teams/managing-organization-members'
33+
- '/enterprise-onboarding/setting-up-organizations-and-teams/managing-your-organizations'
34+
- '/enterprise-onboarding/setting-up-organizations-and-teams/creating-teams'
35+
- '/enterprise-onboarding/setting-up-organizations-and-teams/best-practices-for-organizations-in-your-enterprise'
36+
- id: 'support'
37+
title: 'Creating a support model for your enterprise'
38+
description: 'Learn about {% data variables.product.github %} support and how to set up a support model for your enterprise.'
39+
guides:
40+
- '/enterprise-onboarding/support-for-your-enterprise/understanding-support'
41+
- '/enterprise-onboarding/support-for-your-enterprise/using-the-support-portal'
42+
- '/enterprise-onboarding/support-for-your-enterprise/managing-support-entitlements'
1643
versions:
1744
ghec: '*'
1845
topics:

data/ui.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,11 @@ learning_track_nav:
326326
next_guide: Next
327327
more_guides: More guides →
328328
current_progress: '{i} of {n} in learning path'
329+
journey_track_nav:
330+
prev_article: Previous
331+
next_article: Next
332+
more_articles: More articles →
333+
current_progress: 'Article {i} of {n}'
329334
scroll_button:
330335
scroll_to_top: Scroll to top
331336
popovers:

src/fixtures/fixtures/content/get-started/index.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@ featuredLinks:
1616
- /get-started/foo/bar
1717
guideCards:
1818
- /get-started/foo/autotitling
19+
journeyTracks:
20+
- id: 'getting_started'
21+
title: 'Getting started'
22+
description: 'Learn the basics of our platform.'
23+
guides:
24+
- '/get-started/start-your-journey/hello-world'
25+
- '/get-started/foo/bar'
26+
- id: 'advanced'
27+
title: 'Advanced topics'
28+
description: 'Dive deeper into advanced features.'
29+
guides:
30+
- '/get-started/foo/autotitling'
31+
- '/get-started/start-your-journey/hello-world'
1932
children:
2033
- /start-your-journey
2134
- /foo

src/fixtures/fixtures/content/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ children:
2626
# as if the URL had been `/en/free-pro-team@latest/get-started/anything`.
2727
- search
2828
- get-started
29+
- test-journey
2930
- early-access
3031
- pages
3132
- code-security
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: Test Journey Landing
3+
intro: 'Test page for journey tracks functionality'
4+
layout: journey-landing
5+
versions:
6+
fpt: '*'
7+
ghes: '*'
8+
ghec: '*'
9+
journeyTracks:
10+
- id: 'getting_started'
11+
title: 'Getting started'
12+
description: 'Learn the basics of our platform.'
13+
guides:
14+
- '/get-started/start-your-journey/hello-world'
15+
- '/get-started/foo/bar'
16+
- id: 'advanced'
17+
title: 'Advanced topics'
18+
description: 'Dive deeper into advanced features.'
19+
guides:
20+
- '/get-started/foo/autotitling'
21+
- '/get-started/start-your-journey/hello-world'
22+
---
23+
24+
This is a test page for journey tracks.

src/fixtures/fixtures/data/ui.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,11 @@ learning_track_nav:
326326
next_guide: Next
327327
more_guides: More guides →
328328
current_progress: '{i} of {n} in learning path'
329+
journey_track_nav:
330+
prev_article: Previous
331+
next_article: Next
332+
more_articles: More articles →
333+
current_progress: 'Article {i} of {n}'
329334
scroll_button:
330335
scroll_to_top: Scroll to top
331336
popovers:

src/fixtures/tests/playwright-rendering.spec.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,3 +1056,102 @@ test.describe('LandingCarousel component', () => {
10561056
await expect(cards).toHaveCount(1)
10571057
})
10581058
})
1059+
1060+
test.describe('Journey Tracks', () => {
1061+
test('displays journey tracks on landing pages', async ({ page }) => {
1062+
await page.goto('/get-started?feature=journey-landing')
1063+
1064+
const journeyTracks = page.locator('[data-testid="journey-tracks"]')
1065+
await expect(journeyTracks).toBeVisible()
1066+
1067+
// Check that at least one track is displayed
1068+
const tracks = page.locator('[data-testid="journey-track"]')
1069+
await expect(tracks.first()).toBeVisible()
1070+
1071+
// Verify track has proper structure
1072+
const firstTrack = tracks.first()
1073+
await expect(firstTrack.locator('h3')).toBeVisible() // Track title
1074+
await expect(firstTrack.locator('p')).toBeVisible() // Track description
1075+
})
1076+
1077+
test('track expansion and collapse functionality', async ({ page }) => {
1078+
await page.goto('/get-started?feature=journey-landing')
1079+
1080+
const firstTrack = page.locator('[data-testid="journey-track"]').first()
1081+
const expandButton = firstTrack.locator('summary')
1082+
1083+
// Initially collapsed
1084+
const articlesList = firstTrack.locator('[data-testid="journey-articles"]')
1085+
await expect(articlesList).not.toBeVisible()
1086+
1087+
await expandButton.click()
1088+
await expect(articlesList).toBeVisible()
1089+
1090+
const articles = articlesList.locator('li')
1091+
await expect(articles.first()).toBeVisible()
1092+
1093+
await expandButton.click()
1094+
await expect(articlesList).not.toBeVisible()
1095+
})
1096+
1097+
test('article navigation within tracks', async ({ page }) => {
1098+
await page.goto('/get-started?feature=journey-landing')
1099+
1100+
const firstTrack = page.locator('[data-testid="journey-track"]').first()
1101+
const expandButton = firstTrack.locator('summary')
1102+
1103+
await expandButton.click()
1104+
1105+
// Click on first article
1106+
const firstArticle = firstTrack.locator('[data-testid="journey-articles"] li a').first()
1107+
await expect(firstArticle).toBeVisible()
1108+
1109+
const articleTitle = await firstArticle.textContent()
1110+
expect(articleTitle).toBeTruthy()
1111+
expect(articleTitle!.length).toBeGreaterThan(0)
1112+
})
1113+
1114+
test('preserves version in journey track links', async ({ page }) => {
1115+
await page.goto('/enterprise-cloud@latest/get-started?feature=journey-landing')
1116+
1117+
const firstTrack = page.locator('[data-testid="journey-track"]').first()
1118+
const expandButton = firstTrack.locator('summary')
1119+
await expandButton.click()
1120+
1121+
// article links should preserve the language and version
1122+
const firstArticle = firstTrack.locator('[data-testid="journey-articles"] li a').first()
1123+
const href = await firstArticle.getAttribute('href')
1124+
1125+
expect(href).toContain('/en/')
1126+
expect(href).toContain('enterprise-cloud@latest')
1127+
})
1128+
1129+
test('handles liquid template rendering in track content', async ({ page }) => {
1130+
await page.goto('/get-started?feature=journey-landing')
1131+
1132+
const tracks = page.locator('[data-testid="journey-track"]')
1133+
1134+
// Check that liquid templates are rendered (no raw template syntax visible)
1135+
const trackContent = await tracks.first().textContent()
1136+
expect(trackContent).not.toContain('{{')
1137+
expect(trackContent).not.toContain('}}')
1138+
expect(trackContent).not.toContain('{%')
1139+
expect(trackContent).not.toContain('%}')
1140+
})
1141+
1142+
test('journey navigation components show on article pages', async ({ page }) => {
1143+
// go to an article that's part of a journey track
1144+
await page.goto('/get-started/start-your-journey/hello-world?feature=journey-navigation')
1145+
1146+
// journey next/prev nav components should rende
1147+
const journeyCard = page.locator('[data-testid="journey-track-card"]')
1148+
if (await journeyCard.isVisible()) {
1149+
await expect(journeyCard).toBeVisible()
1150+
}
1151+
1152+
const journeyNav = page.locator('[data-testid="journey-track-nav"]')
1153+
if (await journeyNav.isVisible()) {
1154+
await expect(journeyNav).toBeVisible()
1155+
}
1156+
})
1157+
})

src/frame/components/article/ArticlePage.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { DefaultLayout } from '@/frame/components/DefaultLayout'
77
import { ArticleTitle } from '@/frame/components/article/ArticleTitle'
88
import { useArticleContext } from '@/frame/components/context/ArticleContext'
99
import { LearningTrackNav } from '@/learning-track/components/article/LearningTrackNav'
10+
import { JourneyTrackNav } from '@/journeys/components/JourneyTrackNav'
11+
import { JourneyTrackCard } from '@/journeys/components/JourneyTrackCard'
1012
import { MarkdownContent } from '@/frame/components/ui/MarkdownContent'
1113
import { Lead } from '@/frame/components/ui/Lead'
1214
import { PermissionsStatement } from '@/frame/components/ui/PermissionsStatement'
@@ -42,10 +44,14 @@ export const ArticlePage = () => {
4244
productVideoUrl,
4345
miniTocItems,
4446
currentLearningTrack,
47+
currentJourneyTrack,
4548
supportPortalVaIframeProps,
4649
currentLayout,
4750
} = useArticleContext()
4851
const isLearningPath = !!currentLearningTrack?.trackName
52+
const isJourneyPath = !!currentJourneyTrack?.trackId
53+
// Only show journey track components when feature flag is enabled
54+
const showJourneyTracks = isJourneyPath && router.query?.feature === 'journey-navigation'
4955
const { t } = useTranslation(['pages'])
5056

5157
const introProp = (
@@ -72,6 +78,7 @@ export const ArticlePage = () => {
7278
const toc = (
7379
<>
7480
{isLearningPath && <LearningTrackCard track={currentLearningTrack} />}
81+
{showJourneyTracks && <JourneyTrackCard journey={currentJourneyTrack} />}
7582
{miniTocItems.length > 1 && <MiniTocs miniTocItems={miniTocItems} />}
7683
</>
7784
)
@@ -122,6 +129,11 @@ export const ArticlePage = () => {
122129
<LearningTrackNav track={currentLearningTrack} />
123130
</div>
124131
) : null}
132+
{showJourneyTracks ? (
133+
<div className="container-lg mt-4 px-3">
134+
<JourneyTrackNav context={currentJourneyTrack} />
135+
</div>
136+
) : null}
125137
</>
126138
) : (
127139
<div className="container-xl px-3 px-md-6 my-4">
@@ -148,6 +160,12 @@ export const ArticlePage = () => {
148160
<LearningTrackNav track={currentLearningTrack} />
149161
</div>
150162
) : null}
163+
164+
{showJourneyTracks ? (
165+
<div className="mt-4">
166+
<JourneyTrackNav context={currentJourneyTrack} />
167+
</div>
168+
) : null}
151169
</div>
152170
)}
153171
</DefaultLayout>

src/frame/components/context/ArticleContext.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { SupportPortalVaIframeProps } from '@/frame/components/article/SupportPortalVaIframe'
22
import { createContext, useContext } from 'react'
3+
import type { JourneyContext } from '@/journeys/lib/journey-path-resolver'
34

45
export type LearningTrack = {
56
trackTitle: string
@@ -34,6 +35,7 @@ export type ArticleContextT = {
3435
product?: string
3536
productVideoUrl?: string
3637
currentLearningTrack?: LearningTrack
38+
currentJourneyTrack?: JourneyContext
3739
detectedPlatforms: Array<string>
3840
detectedTools: Array<string>
3941
allTools: Record<string, string>
@@ -98,6 +100,7 @@ export const getArticleContextFromRequest = (req: any): ArticleContextT => {
98100
product: page.product || '',
99101
productVideoUrl: page.product_video || '',
100102
currentLearningTrack: req.context.currentLearningTrack,
103+
currentJourneyTrack: req.context.currentJourneyTrack,
101104
detectedPlatforms: page.detectedPlatforms || [],
102105
detectedTools: page.detectedTools || [],
103106
allTools: page.allToolsParsed || [], // this is set at the page level, see lib/page.js

src/frame/lib/frontmatter.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,39 @@ export const schema = {
197197
learningTracks: {
198198
type: 'array',
199199
},
200+
// Journey tracks for journey landing pages
201+
journeyTracks: {
202+
type: 'array',
203+
items: {
204+
type: 'object',
205+
required: ['id', 'title', 'guides'],
206+
properties: {
207+
id: {
208+
type: 'string',
209+
description: 'Unique identifier for the journey track',
210+
},
211+
title: {
212+
type: 'string',
213+
translatable: true,
214+
description: 'Display title for the journey track',
215+
},
216+
description: {
217+
type: 'string',
218+
translatable: true,
219+
description: 'Optional description for the journey track',
220+
},
221+
guides: {
222+
type: 'array',
223+
items: {
224+
type: 'string',
225+
},
226+
description: 'Array of article paths that make up this journey track',
227+
},
228+
},
229+
additionalProperties: false,
230+
},
231+
description: 'Array of journey tracks for journey landing pages',
232+
},
200233
// Used in `product-landing.html`
201234
beta_product: {
202235
type: 'boolean',

0 commit comments

Comments
 (0)