mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
docs(docs-infra): Update navigation status
This commit is contained in:
committed by
Jessica Janiuk
parent
6b3e46a872
commit
59e2041847
@@ -9,11 +9,17 @@
|
||||
>
|
||||
@for (itemGroup of groupItems(navigationItems, preserveOtherCategoryOrder); track $index) {
|
||||
@let groupLabel = itemGroup[0];
|
||||
@let items = itemGroup[1];
|
||||
@let group = itemGroup[1];
|
||||
@let items = group.items;
|
||||
@let firstItem = items[0];
|
||||
|
||||
@if (groupLabel && collapsableLevel() !== firstItem.level && items.length > 1) {
|
||||
<li class="docs-navigation-group">{{ groupLabel }}</li>
|
||||
<li class="docs-navigation-group">
|
||||
<span>{{ groupLabel }}</span>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="itemStatus; context: {$implicit: {status: group.status}}"
|
||||
/>
|
||||
</li>
|
||||
}
|
||||
@for (item of items; track $index) {
|
||||
<li
|
||||
|
||||
@@ -188,8 +188,12 @@ a,
|
||||
}
|
||||
|
||||
.docs-navigation-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem 0.5rem 0.5rem 1rem;
|
||||
background: var(--septenary-contrast);
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,32 @@ const navigationItems: NavigationItem[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const navigationItemsWithCategoryStatus: NavigationItem[] = [
|
||||
{
|
||||
label: 'Forms',
|
||||
level: 1,
|
||||
categoriesStatus: [{'Signal Forms': 'new'}],
|
||||
children: [],
|
||||
},
|
||||
];
|
||||
|
||||
navigationItemsWithCategoryStatus[0].children = [
|
||||
{
|
||||
label: 'Overview',
|
||||
path: 'guide/forms',
|
||||
level: 2,
|
||||
category: 'Signal Forms',
|
||||
parent: navigationItemsWithCategoryStatus[0],
|
||||
},
|
||||
{
|
||||
label: 'Signals',
|
||||
path: 'guide/forms/signals',
|
||||
level: 2,
|
||||
category: 'Signal Forms',
|
||||
parent: navigationItemsWithCategoryStatus[0],
|
||||
},
|
||||
];
|
||||
|
||||
describe('NavigationList', () => {
|
||||
let component: NavigationList;
|
||||
let fixture: ComponentFixture<NavigationList>;
|
||||
@@ -58,6 +84,20 @@ describe('NavigationList', () => {
|
||||
expect(nonClickableItem.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should show category status on grouped navigation headers', async () => {
|
||||
fixture.componentRef.setInput('navigationItems', [...navigationItemsWithCategoryStatus]);
|
||||
await fixture.whenStable();
|
||||
|
||||
const categoryGroup = fixture.debugElement.query(By.css('.docs-navigation-group'));
|
||||
const categoryStatus = fixture.debugElement.query(
|
||||
By.css('.docs-navigation-group .docs-new-item'),
|
||||
);
|
||||
|
||||
expect(categoryGroup.nativeElement.innerText).toContain('Signal Forms');
|
||||
expect(categoryStatus).toBeTruthy();
|
||||
expect(categoryStatus.nativeElement.innerText).toBe('New');
|
||||
});
|
||||
|
||||
it('should append `docs-navigation-list-dropdown` when isDropdownView is true', async () => {
|
||||
fixture.componentRef.setInput('isDropdownView', true);
|
||||
await fixture.whenStable();
|
||||
|
||||
@@ -73,14 +73,27 @@ export class NavigationList {
|
||||
return items.some((item) => !!item.category);
|
||||
}
|
||||
|
||||
private getCategoryStatus(item: NavigationItem, category: string): 'new' | 'updated' | undefined {
|
||||
const categoriesStatus = item.parent?.categoriesStatus;
|
||||
|
||||
if (!categoriesStatus) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return categoriesStatus.find((status) => status[category])?.[category];
|
||||
}
|
||||
|
||||
protected groupItems(
|
||||
items: NavigationItem[],
|
||||
preserveOtherCategoryOrder: boolean,
|
||||
): Map<string, NavigationItem[]> {
|
||||
): Map<string, {items: NavigationItem[]; status: 'new' | 'updated' | undefined}> {
|
||||
const hasCategories = this.hasCategories(items);
|
||||
if (hasCategories) {
|
||||
const others: NavigationItem[] = [];
|
||||
const categorizedItems = new Map<string, NavigationItem[]>();
|
||||
const categorizedItems = new Map<
|
||||
string,
|
||||
{items: NavigationItem[]; status: 'new' | 'updated' | undefined}
|
||||
>();
|
||||
for (const item of items) {
|
||||
const category = item.category || 'Other';
|
||||
if (!preserveOtherCategoryOrder && category === 'Other') {
|
||||
@@ -88,16 +101,20 @@ export class NavigationList {
|
||||
continue;
|
||||
}
|
||||
if (!categorizedItems.has(category)) {
|
||||
categorizedItems.set(category, []);
|
||||
categorizedItems.set(category, {
|
||||
items: [],
|
||||
status: this.getCategoryStatus(item, category),
|
||||
});
|
||||
}
|
||||
categorizedItems.get(category)!.push(item);
|
||||
categorizedItems.get(category)!.items.push(item);
|
||||
}
|
||||
if (others.length) {
|
||||
categorizedItems.set('Other', others);
|
||||
categorizedItems.set('Other', {items: others, status: undefined});
|
||||
}
|
||||
|
||||
return categorizedItems;
|
||||
} else {
|
||||
return new Map([['', items]]);
|
||||
return new Map([['', {items, status: undefined}]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ export interface NavigationItem {
|
||||
contentPath?: string;
|
||||
status?: 'new' | 'updated';
|
||||
category?: string;
|
||||
categoriesStatus?: Record<string, 'new' | 'updated'>[];
|
||||
isCrossReferenced?: boolean;
|
||||
preserveOtherCategoryOrder?: boolean; // true by default
|
||||
}
|
||||
|
||||
@@ -313,13 +313,11 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
label: 'Overview',
|
||||
path: 'guide/di',
|
||||
contentPath: 'guide/di/overview',
|
||||
status: 'updated',
|
||||
},
|
||||
{
|
||||
label: 'Creating and using services',
|
||||
path: 'guide/di/creating-and-using-services',
|
||||
contentPath: 'guide/di/creating-and-using-services',
|
||||
status: 'updated',
|
||||
},
|
||||
{
|
||||
label: 'Lazy loading services',
|
||||
@@ -331,7 +329,6 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
label: 'Defining dependency providers',
|
||||
path: 'guide/di/defining-dependency-providers',
|
||||
contentPath: 'guide/di/defining-dependency-providers',
|
||||
status: 'updated',
|
||||
},
|
||||
{
|
||||
label: 'Injection context',
|
||||
@@ -363,7 +360,6 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
},
|
||||
{
|
||||
label: 'Routing',
|
||||
status: 'updated',
|
||||
children: [
|
||||
{
|
||||
label: 'Overview',
|
||||
@@ -419,7 +415,6 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
label: 'Testing routing and navigation',
|
||||
path: 'guide/routing/testing',
|
||||
contentPath: 'guide/routing/testing',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Other routing tasks',
|
||||
@@ -435,13 +430,11 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
label: 'Rendering strategies',
|
||||
path: 'guide/routing/rendering-strategies',
|
||||
contentPath: 'guide/routing/rendering-strategies',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Customizing route behavior',
|
||||
path: 'guide/routing/customizing-route-behavior',
|
||||
contentPath: 'guide/routing/customizing-route-behavior',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Router reference',
|
||||
@@ -459,6 +452,11 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
label: 'Forms',
|
||||
status: 'updated',
|
||||
preserveOtherCategoryOrder: true,
|
||||
categoriesStatus: [
|
||||
{
|
||||
'Signal Forms': 'new',
|
||||
},
|
||||
],
|
||||
children: [
|
||||
{
|
||||
label: 'Overview',
|
||||
@@ -471,98 +469,84 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
path: 'guide/forms/signals/overview',
|
||||
contentPath: 'guide/forms/signals/overview',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Form models',
|
||||
path: 'guide/forms/signals/models',
|
||||
contentPath: 'guide/forms/signals/models',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Form model design',
|
||||
path: 'guide/forms/signals/model-design',
|
||||
contentPath: 'guide/forms/signals/designing-your-form-model',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Field state management',
|
||||
path: 'guide/forms/signals/field-state-management',
|
||||
contentPath: 'guide/forms/signals/field-state-management',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Validation',
|
||||
path: 'guide/forms/signals/validation',
|
||||
contentPath: 'guide/forms/signals/validation',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Form logic',
|
||||
path: 'guide/forms/signals/form-logic',
|
||||
contentPath: 'guide/forms/signals/form-logic',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Cross-field logic',
|
||||
path: 'guide/forms/signals/cross-field-logic',
|
||||
contentPath: 'guide/forms/signals/cross-field-logic',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Form submission',
|
||||
path: 'guide/forms/signals/form-submission',
|
||||
contentPath: 'guide/forms/signals/form-submission',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Schemas',
|
||||
path: 'guide/forms/signals/schemas',
|
||||
contentPath: 'guide/forms/signals/schemas',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Field metadata',
|
||||
path: 'guide/forms/signals/field-metadata',
|
||||
contentPath: 'guide/forms/signals/field-metadata',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Async operations',
|
||||
path: 'guide/forms/signals/async-operations',
|
||||
contentPath: 'guide/forms/signals/async-operations',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Custom controls',
|
||||
path: 'guide/forms/signals/custom-controls',
|
||||
contentPath: 'guide/forms/signals/custom-controls',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Comparison with other form systems',
|
||||
path: 'guide/forms/signals/comparison',
|
||||
contentPath: 'guide/forms/signals/comparison',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Migrating from Reactive Forms',
|
||||
path: 'guide/forms/signals/migration',
|
||||
contentPath: 'guide/forms/signals/migration',
|
||||
category: 'Signal Forms',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Reactive forms',
|
||||
@@ -887,13 +871,11 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
},
|
||||
{
|
||||
label: 'Animations',
|
||||
status: 'updated',
|
||||
children: [
|
||||
{
|
||||
label: 'Enter and Leave animations',
|
||||
path: 'guide/animations',
|
||||
contentPath: 'guide/animations/enter-and-leave',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Complex Animations with CSS',
|
||||
@@ -1115,7 +1097,6 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
label: 'Style Guide',
|
||||
path: 'style-guide',
|
||||
contentPath: 'best-practices/style-guide',
|
||||
status: 'updated',
|
||||
},
|
||||
{
|
||||
label: 'Security',
|
||||
@@ -1354,7 +1335,6 @@ export const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
label: 'Tailwind',
|
||||
path: 'guide/tailwind',
|
||||
contentPath: 'guide/tailwind',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Angular Fire',
|
||||
@@ -1760,25 +1740,21 @@ export const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [
|
||||
label: 'NgClass to Class',
|
||||
path: 'reference/migrations/ngclass-to-class',
|
||||
contentPath: 'reference/migrations/ngclass-to-class',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'NgStyle to Style',
|
||||
path: 'reference/migrations/ngstyle-to-style',
|
||||
contentPath: 'reference/migrations/ngstyle-to-style',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'Router Testing Module Migration',
|
||||
path: 'reference/migrations/router-testing-module-migration',
|
||||
contentPath: 'reference/migrations/router-testing-module-migration',
|
||||
status: 'new',
|
||||
},
|
||||
{
|
||||
label: 'CommonModule to Standalone',
|
||||
path: 'reference/migrations/common-to-standalone',
|
||||
contentPath: 'reference/migrations/common-to-standalone',
|
||||
status: 'new',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user