Skip to content
Closed
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
2 changes: 2 additions & 0 deletions adev/src/app/core/constants/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const DEFAULT_PAGES = {
TUTORIALS: 'tutorials',
PLAYGROUND: 'playground',
UPDATE: 'update-guide',
RANDOM: 'random',
} as const;

export const PAGE_PREFIX = {
Expand All @@ -25,4 +26,5 @@ export const PAGE_PREFIX = {
REFERENCE: 'reference',
TUTORIALS: 'tutorials',
UPDATE: 'update-guide',
RANDOM: 'random',
} as const;
Empty file.
55 changes: 55 additions & 0 deletions adev/src/app/features/random/random.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {Router} from '@angular/router';
import Random from './random';
import {SUB_NAVIGATION_DATA} from '../../routing/sub-navigation-data';

describe('Random', () => {
let component: Random;
let fixture: ComponentFixture<Random>;
let router: Router;

beforeEach(async () => {
const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);

await TestBed.configureTestingModule({
imports: [Random],
providers: [{provide: Router, useValue: routerSpy}],
}).compileComponents();

router = TestBed.inject(Router);
fixture = TestBed.createComponent(Random);
component = fixture.componentInstance;
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should redirect to a random path on init', () => {
fixture.detectChanges(); // Triggers ngOnInit

expect(router.navigateByUrl).toHaveBeenCalled();
const call = (router.navigateByUrl as jasmine.Spy).calls.mostRecent();
const navigatedUrl = call.args[0];
const options = call.args[1];

expect(options.replaceUrl).toBeTrue();

// Check if navigatedUrl is one of the possible paths
const allPaths = [
...SUB_NAVIGATION_DATA.docs,
...SUB_NAVIGATION_DATA.reference,
...SUB_NAVIGATION_DATA.tutorials,
].flatMap((item) => {
const paths: string[] = [];
const traverse = (node: any) => {
if (node.path && !node.path.startsWith('http')) paths.push(`/${node.path}`);
if (node.children) node.children.forEach(traverse);
};
traverse(item);
return paths;
});

expect(allPaths).toContain(navigatedUrl);
});
});
32 changes: 32 additions & 0 deletions adev/src/app/features/random/random.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {Component, inject, OnInit} from '@angular/core';
import {Router} from '@angular/router';
import {SUB_NAVIGATION_DATA} from '../../routing/sub-navigation-data';
import {flatNavigationData} from '@angular/docs';

@Component({
selector: 'adev-random',
standalone: true,
template: ``,
})
export default class Random implements OnInit {
private readonly router = inject(Router);

ngOnInit(): void {
const allItems = [
...flatNavigationData(SUB_NAVIGATION_DATA.docs),
...flatNavigationData(SUB_NAVIGATION_DATA.reference),
...flatNavigationData(SUB_NAVIGATION_DATA.tutorials),
];

const paths = allItems
.map((item) => item.path)
.filter((path): path is string => !!path && !path.startsWith('http'));

if (paths.length > 0) {
const randomPath = paths[Math.floor(Math.random() * paths.length)];
this.router.navigateByUrl(`/${randomPath}`, {replaceUrl: true});
} else {
this.router.navigateByUrl('/', {replaceUrl: true});
}
}
Comment on lines +15 to +31
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this logic does the job well!
just one thing but nit!

The current implementation can redirect the user back to the page they came from.
If I'm on /guide/components/selectors and hit /random, it could randomly pick /guide/components/selectors again and send me right back where I started.

}
9 changes: 6 additions & 3 deletions adev/src/app/routing/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ const cliReferencePageRoutes = mapNavigationItemsToRoutes(
referenceNavigationItems.filter((r) => r.path?.startsWith(`${PAGE_PREFIX.CLI}/`)),
{
loadComponent: () =>
import(
'../features/references/cli-reference-details-page/cli-reference-details-page.component'
),
import('../features/references/cli-reference-details-page/cli-reference-details-page.component'),
data: commonReferenceRouteData,
},
).map((route) => ({
Expand Down Expand Up @@ -148,6 +146,11 @@ export const routes: Route[] = [
loadComponent: () => import('../features/playground/playground.component'),
data: {...commonTutorialRouteData, label: 'Playground'},
},
{
path: PAGE_PREFIX.RANDOM,
loadComponent: () => import('../features/random/random'),
Copy link
Copy Markdown
Contributor

@SkyZeroZx SkyZeroZx Apr 5, 2026

Choose a reason for hiding this comment

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

Not really sure it’s worth the cost of adding an extra component.

We could just use redirectTo for this: https://angular.dev/guide/routing/redirecting-routes#conditional-redirects

Or maybe browserUrl for this case: https://angular.dev/guide/routing/navigate-to-routes#display-a-different-url-in-the-address-bar

Is there any specific reason to do it this way?

wdyt some like

export const randomRedirectGuard: CanActivateFn = () => {
   // logic to build random URL

  return router.navigateByUrl(random, {
    browserUrl: '/random',
  });
};

export const routes = [
  {
    path: 'random',
    children: [],
    canActivate: [randomRedirectGuard],
   } 
  ]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, there's no specific technical reason. I just wanted to set it up this way and see the initial feedback. I agree that the component is perhaps excessive.

Copy link
Copy Markdown
Contributor

@erkamyaman erkamyaman Apr 6, 2026

Choose a reason for hiding this comment

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

i agree on that one with @SkyZeroZx we don't need a new component

data: {label: 'Random topic'},
},
...SUB_NAVIGATION_ROUTES,
...API_REFERENCE_ROUTES,
...FOOTER_ROUTES,
Expand Down
Loading