Skip to content
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
31 changes: 19 additions & 12 deletions apps/cns-website/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,33 @@ import { ResearchDataSchema } from './schemas/research.schema';
import { TagsDataSchema } from './schemas/tags.schema';
import { createMountRedirectRoute } from './utils/mount-redirect';

/** Base URL for content and indexes */
const BASE_URL = 'https://cns.iu.edu/';

/** People index URL */
const PEOPLE_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-people.json';
const PEOPLE_INDEX_URL = BASE_URL + 'assets/indexes/app-people.json';
/** Featured content index URL */
const FEATURED_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-featured.json';
const FEATURED_INDEX_URL = BASE_URL + 'assets/indexes/app-featured.json';
/** News content index URL */
const NEWS_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-news.json';
const NEWS_INDEX_URL = BASE_URL + 'assets/indexes/app-news.json';
/** Publications content index URL */
const PUBLICATIONS_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-publications.json';
const PUBLICATIONS_INDEX_URL = BASE_URL + 'assets/indexes/app-publications.json';
/** Publication types content index URL */
const PUBLICATION_TYPES_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-publication-types.json';
const PUBLICATION_TYPES_INDEX_URL = BASE_URL + 'assets/indexes/app-publication-types.json';
/** Events content index URL */
const EVENT_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-events.json';
const EVENT_INDEX_URL = BASE_URL + 'assets/indexes/app-events.json';
/** Event types content index URL */
const EVENT_TYPES_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-event-types.json';
const EVENT_TYPES_INDEX_URL = BASE_URL + 'assets/indexes/app-event-types.json';
/** Funding content index URL */
const FUNDING_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-funding.json';
const FUNDING_INDEX_URL = BASE_URL + 'assets/indexes/app-funding.json';
/** Funding types content index URL */
const FUNDING_TYPES_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-funding-types.json';
const FUNDING_TYPES_INDEX_URL = BASE_URL + 'assets/indexes/app-funding-types.json';
/** Visualizations content index URL */
const VISUALIZATIONS_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-visualizations.json';
const VISUALIZATIONS_INDEX_URL = BASE_URL + 'assets/indexes/app-visualizations.json';
/** Tags content index URL */
const TAGS_INDEX_URL = 'https://cns-iu.github.io/cns-website/assets/indexes/app-tags.json';
const TAGS_INDEX_URL = BASE_URL + 'assets/indexes/app-tags.json';
/** Base URL for person content */
const PERSON_BASE_URL = 'https://cns-iu.github.io/cns-website/content/people';
const PERSON_BASE_URL = BASE_URL + 'content/people';

/** Application routes */
export const appRoutes: Route[] = [
Expand Down Expand Up @@ -134,6 +137,10 @@ export const appRoutes: Route[] = [
data: createYamlSpecResolver('assets/content/privacy-policy-page/data.yaml', ContentPageDataSchema),
},
},
{
path: 'publications',
redirectTo: '/research?category=publication&view=list&group-by=year',
},
{
path: 'research',
component: ResearchPageComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
[hraFeature]="category.id | slugify"
[toggled]="isMenuActive(category)"
(toggledChange)="toggleMenu(category)"
(keydown.tab)="moveFocusToMenu(category)"
>
{{ category.label }}
</hra-navigation-category-toggle>
Expand All @@ -55,7 +56,7 @@
(overlayOutsideClick)="closeMenu(category)"
(detach)="closeMenu(category)"
>
<cns-mega-menu cdkTrapFocus cdkTrapFocusAutoCapture [menu]="category" />
<cns-mega-menu cdkTrapFocus [menu]="category" />
</ng-template>
} @else {
<a
Expand Down
27 changes: 26 additions & 1 deletion apps/cns-website/src/app/components/header/header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
input,
signal,
viewChild,
viewChildren,
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MatIconModule } from '@angular/material/icon';
Expand Down Expand Up @@ -92,12 +93,22 @@ export class HeaderComponent {
/** Currently open menu or undefined */
private readonly activeMenu = signal<Menu | 'mobile' | undefined>(undefined);

/** Initialize the header */
/** Focus traps for the open menus. Used to manage focus when menus are opened and closed */
private readonly focusTraps = viewChildren(CdkTrapFocus);

/** Stores the last focused element before a menu was opened, so that focus can be returned to it when the menu is closed */
private lastFocusedElement?: HTMLElement;

/** Initialize the header and set cleanup behaviors */
constructor() {
effect((cleanup) => {
if (this.activeMenu() !== undefined) {
const observer = this.attachResizeObserver();
cleanup(() => observer.disconnect());
cleanup(() => {
this.lastFocusedElement?.focus();
this.lastFocusedElement = undefined;
});
}
});

Expand Down Expand Up @@ -139,6 +150,20 @@ export class HeaderComponent {
this.activeMenu.update((current) => (menu !== undefined && current !== menu ? current : undefined));
}

/**
* Moves focus to the specified menu if it is active
* @param menu Menu to move focus to
*/
moveFocusToMenu(menu: Menu): void {
if (this.isMenuActive(menu)) {
const traps = this.focusTraps();
if (traps.length > 0) {
this.lastFocusedElement = document.activeElement as HTMLElement;
traps[0].focusTrap.focusInitialElementWhenReady();
}
}
}

/**
* Scrolls to the top of the page if the menu item is not an external link
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
hraClickEvent
class="featured-bottom"
tabindex="0"
cdkFocusRegionStart
cdkFocusInitial
[hraLink]="featured.url"
[hraLinkExternal]="featured.external"
Expand All @@ -35,7 +34,7 @@
<div class="right-side">
<div class="nav-items">
<div class="groups">
@for (group of menu().items; track group; let outerFirst = $first) {
@for (group of menu().items; track group) {
<div class="group">
<div class="group-label">
{{ group.label }}
Expand All @@ -44,15 +43,12 @@
<mat-divider class="divider" />
<div class="items">
@for (item of group.items; track item) {
@let isFocusRegionStart = $first && outerFirst && !menu().featured;
<a
mat-button
hraSecondaryButton
hraClickEvent
class="item-label"
tabindex="0"
[attr.cdkFocusRegionStart]="isFocusRegionStart ? '' : null"
[attr.cdkFocusInitial]="isFocusRegionStart ? '' : null"
[hraFeature]="item.label | slugify"
[hraLink]="item.url"
[hraLinkExternal]="item.external"
Expand All @@ -70,12 +66,7 @@

<div class="socials">
@for (id of socials(); track id) {
<hra-social-media-button
size="large"
variant="color"
[attr.cdkFocusRegionEnd]="$last ? '' : null"
[id]="$any(id)"
/>
<hra-social-media-button size="large" variant="color" [id]="$any(id)" />
}
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ <h3 hra-section-link underlined class="title">{{ group.label }}</h3>
[imageSrc]="getImageUrl(item)"
[tagline]="item.title"
[date]="(item.dateStart | date) ?? ''"
[link]="item.link || ''"
[link]="item.link"
[external]="true"
[tags]="getTagItems(item.tags)"
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<img class="image" alt="" [attr.src]="imageSrc() | assetUrl" />
<div class="content">
<div class="date">{{ date() }}</div>
<a class="tagline-link" hraHyperlink [hraLink]="link()" [hraLinkExternal]="external()" [hraPlainTooltip]="tagline()">
{{ tagline() }}
</a>
@if (link(); as link) {
<a class="tagline-link" hraHyperlink [hraLink]="link" [hraLinkExternal]="external()" [hraPlainTooltip]="tagline()">
{{ tagline() }}
</a>
} @else {
<div class="tagline" [hraPlainTooltip]="tagline()">{{ tagline() }}</div>
}
@if (tags().length > 0) {
<mat-chip-set class="tags">
@for (tag of tags(); track tag.name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,19 @@
color: vars.$on-secondary-fixed;
}

.tagline-link {
.tagline-link,
.tagline {
color: vars.$tertiary;
text-decoration: underline;
cursor: pointer;
margin-top: 0.5rem;
@include utils.use-font(label, large);
@include utils.line-clamp(2);
}

.tagline-link {
text-decoration: underline;
cursor: pointer;
}

.tags {
padding-top: 1.25rem;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class GalleryCardComponent {
/** Date to display */
readonly date = input.required<string>();
/** URL for the tagline link */
readonly link = input.required<string>();
readonly link = input<string>();
/** Whether the link opens in new tab */
readonly external = input<boolean>(false);
/** Tags to display */
Expand Down
Loading