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
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
"@angular/platform-browser-dynamic": "^19.2.0",
"@angular/router": "^19.2.0",
"@angular/service-worker": "^19.2.0",
"@ngx-translate/core": "^16.0.4",
"@ngx-translate/http-loader": "^16.0.1",
"@ngxs/devtools-plugin": "^19.0.0",
"@ngxs/logger-plugin": "^19.0.0",
"@ngxs/store": "^19.0.0",
Expand Down
9 changes: 8 additions & 1 deletion src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import {
ApplicationConfig,
importProvidersFrom,
provideZoneChangeDetection,
} from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideStore } from '@ngxs/store';
Expand All @@ -10,6 +14,8 @@ import { provideHttpClient } from '@angular/common/http';
import { ConfirmationService } from 'primeng/api';
import { STATES } from '@core/constants/ngxs-states.constant';
import { provideServiceWorker } from '@angular/service-worker';
import { provideTranslation } from '@core/helpers/i18n.helper';
import { TranslateModule } from '@ngx-translate/core';

export const appConfig: ApplicationConfig = {
providers: [
Expand All @@ -35,5 +41,6 @@ export const appConfig: ApplicationConfig = {
registrationStrategy: 'registerWhenStable:30000',
}),
ConfirmationService,
importProvidersFrom(TranslateModule.forRoot(provideTranslation())),
],
};
13 changes: 0 additions & 13 deletions src/app/app.module.ts

This file was deleted.

31 changes: 21 additions & 10 deletions src/app/core/components/footer/footer.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@
<div class="footer-content">
<div class="footer-nav">
<div class="footer-links">
<a href="#">Center for Open Science</a>
<a href="#">{{ "footer.links.centerForOpenScience" | translate }}</a>
<span class="separator">|</span>
<a href="#">Reproducibility Project: Psychology</a>
<a href="#">{{
"footer.links.reproducibilityProjectPsychology" | translate
}}</a>
<span class="separator">|</span>
<a href="#">Reproducibility Project: Cancer Biology</a>
<a href="#">{{
"footer.links.reproducibilityProjectCancerBiology" | translate
}}</a>
</div>

<div class="footer-socials">
@for (icon of socialIcons; track icon.name) {
<a [href]="icon.url" [attr.aria-label]="icon.ariaLabel">
<a
[href]="icon.url"
[attr.aria-label]="'footer.socials.' + icon.name | translate"
>
<img
alt="social media icon"
width="37"
Expand All @@ -25,18 +32,22 @@

<div class="footer-secondary-nav">
<div class="footer-links">
<a routerLink="/terms-of-use">Terms of Use</a>
<a routerLink="/terms-of-use">{{
"footer.links.termsOfUse" | translate
}}</a>
<span class="separator">|</span>
<a routerLink="/privacy-policy">Privacy Policy</a>
<a routerLink="/privacy-policy">{{
"footer.links.privacyPolicy" | translate
}}</a>
<span class="separator">|</span>
<a href="#">Status</a>
<a href="#">{{ "footer.links.status" | translate }}</a>
<span class="separator">|</span>
<a href="#">API</a>
<a href="#">{{ "footer.links.api" | translate }}</a>
<span class="separator">|</span>
<a href="#">TOP Guidelines</a>
<a href="#">{{ "footer.links.topGuidelines" | translate }}</a>
</div>

<div class="footer-copyright">Copyright © 2011-2025</div>
<div class="footer-copyright">{{ "footer.copyright" | translate }}</div>
</div>
</div>
</footer>
3 changes: 2 additions & 1 deletion src/app/core/components/footer/footer.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { RouterLink } from '@angular/router';
import { IS_PORTRAIT, IS_XSMALL } from '@shared/utils/breakpoints.tokens';
import { toSignal } from '@angular/core/rxjs-interop';
import { NgOptimizedImage } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';

@Component({
standalone: true,
selector: 'osf-footer',
imports: [RouterLink, NgOptimizedImage],
imports: [RouterLink, NgOptimizedImage, TranslateModule],
templateUrl: './footer.component.html',
styleUrl: './footer.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
Expand Down
8 changes: 6 additions & 2 deletions src/app/core/components/header/header.component.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<osf-breadcrumb />
<!--<a [routerLink]="authButtonLink()" class="p-button">{{ authButtonText() }}</a>-->
<!--<a [routerLink]="authButtonLink()" class="p-button">{{ authButtonText() | translate }}</a>-->

<div class="dropdown-button ml-auto" style="min-width: 7rem">
<p-button (click)="menu.toggle($event)">
{{ currentUser()?.fullName }}
<i class="pi pi-chevron-down"></i>
</p-button>

<p-menu #menu [model]="items" popup></p-menu>
<p-menu #menu [model]="items" popup>
<ng-template #item let-item>
<a class="p-menu-item-link">{{ item.label | translate }}</a>
</ng-template>
</p-menu>
</div>
19 changes: 14 additions & 5 deletions src/app/core/components/header/header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ import { MenuModule } from 'primeng/menu';
import { ButtonModule } from 'primeng/button';
import { Store } from '@ngxs/store';
import { UserSelectors } from '@core/store/user/user.selectors';
import { TranslatePipe } from '@ngx-translate/core';

@Component({
standalone: true,
selector: 'osf-header',
imports: [RouterLink, BreadcrumbComponent, MenuModule, ButtonModule],
imports: [
BreadcrumbComponent,
MenuModule,
ButtonModule,
TranslatePipe,
RouterLink,
],
templateUrl: './header.component.html',
styleUrl: './header.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
Expand All @@ -28,17 +35,19 @@ export class HeaderComponent {

items = [
{
label: 'My profile',
label: 'navigation.myProfile',
command: () => this.#router.navigate(['my-profile']),
},
{ label: 'Settings', command: () => console.log('Settings') },
{ label: 'Log out', command: () => console.log('Log out') },
{ label: 'navigation.settings', command: () => console.log('Settings') },
{ label: 'navigation.logOut', command: () => console.log('Log out') },
];

#currentUrl = toSignal(this.#router.events.pipe(map(() => this.#router.url)));

protected readonly authButtonText = computed(() =>
this.#currentUrl()?.includes('sign-up') ? 'Sign In' : 'Sign Up',
this.#currentUrl()?.includes('sign-up')
? 'navigation.signIn'
: 'navigation.signUp',
);

protected readonly authButtonLink = computed(() =>
Expand Down
14 changes: 9 additions & 5 deletions src/app/core/components/nav-menu/nav-menu.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@
[routerLink]="item.routerLink"
routerLinkActive="active"
[routerLinkActiveOptions]="{
exact: item.label !== 'My Projects' ? item.useExactMatch : true,
exact:
item.label !== 'navigation.myProjects' ? item.useExactMatch : true,
}"
class="nav-link flex"
[class.mt-5]="item.label === 'Settings' || item.label === 'My Projects'"
[class.mt-5]="
item.label === 'navigation.settings' ||
item.label === 'navigation.myProjects'
"
>
@if (item.icon) {
<i [class]="item.icon" class="nav-icon"></i>
}
<span>{{ item.label }}</span>
<span>{{ item.label | translate }}</span>
@if (item.items) {
<i
[class]="item.expanded ? 'osf-icon-arrow-down' : 'osf-icon-arrow'"
Expand All @@ -22,7 +26,7 @@
}
</a>

@if (item.label === "My Projects" && isProjectRoute()) {
@if (item.label === "navigation.myProjects" && isProjectRoute()) {
<div class="ml-4">
<p-panelMenu [model]="myProjectMenuItems" [multiple]="false">
<ng-template #item let-item>
Expand All @@ -39,7 +43,7 @@
@if (item.icon) {
<i [class]="item.icon" class="nav-icon"></i>
}
<span>{{ item.label }}</span>
<span>{{ item.label | translate }}</span>
@if (item.items) {
<i
[class]="
Expand Down
3 changes: 2 additions & 1 deletion src/app/core/components/nav-menu/nav-menu.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import { MenuItem } from 'primeng/api';
import { toSignal } from '@angular/core/rxjs-interop';
import { filter, map } from 'rxjs';
import { NavItem } from '@shared/entities/nav-item.interface';
import { TranslatePipe } from '@ngx-translate/core';

@Component({
selector: 'osf-nav-menu',
imports: [RouterLinkActive, RouterLink, PanelMenuModule],
imports: [RouterLinkActive, RouterLink, PanelMenuModule, TranslatePipe],
templateUrl: './nav-menu.component.html',
styleUrl: './nav-menu.component.scss',
})
Expand Down
47 changes: 30 additions & 17 deletions src/app/core/constants/nav-items.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,90 @@ import { NavItem } from '@shared/entities/nav-item.interface';
import { MenuItem } from 'primeng/api';

export const NAV_ITEMS: NavItem[] = [
{ path: '/home', label: 'Home', icon: 'home', useExactMatch: true },
{ path: '/search', label: 'Search OSF', icon: 'search', useExactMatch: true },
{
path: '/home',
label: 'navigation.home',
icon: 'home',
useExactMatch: true,
},
{
path: '/search',
label: 'navigation.searchOsf',
icon: 'search',
useExactMatch: true,
},
{
path: '/support',
label: 'Support',
label: 'navigation.support',
icon: 'support',
useExactMatch: true,
},
{
path: '/my-projects',
label: 'My Projects',
label: 'navigation.myProjects',
icon: 'my-projects',
useExactMatch: true,
},
{
path: '/settings',
label: 'Settings',
label: 'navigation.settings',
icon: 'settings',
isCollapsible: true,
useExactMatch: true,
items: [
{
path: '/settings/profile-settings',
label: 'Profile Settings',
label: 'navigation.profileSettings',
useExactMatch: true,
},
{
path: '/settings/account-settings',
label: 'Account Settings',
label: 'navigation.accountSettings',
useExactMatch: true,
},
{
path: '/settings/addons',
label: 'Configure Addon Accounts',
label: 'navigation.configureAddonAccounts',
useExactMatch: false,
},
{
path: '/settings/notifications',
label: 'Notifications',
label: 'navigation.notifications',
useExactMatch: true,
},
{
path: '/settings/developer-apps',
label: 'Developer Apps',
label: 'navigation.developerApps',
useExactMatch: true,
},
{
path: '/settings/tokens',
label: 'Personal Access Tokens',
label: 'navigation.personalAccessTokens',
useExactMatch: true,
},
],
},
{
path: '/donate',
label: 'Donate',
label: 'navigation.donate',
icon: 'donate',
useExactMatch: true,
},
];

export const PROJECT_MENU_ITEMS: MenuItem[] = [
{
label: 'Project details',
label: 'navigation.project.details',
icon: 'osf-icon-my-projects',
expanded: true,
items: [
{ label: 'Overview', routerLink: 'overview' },
{ label: 'Metadata', routerLink: 'metadata' },
{ label: 'Files', routerLink: 'files' },
{ label: 'Registrations', routerLink: 'registrations' },
{ label: 'navigation.project.overview', routerLink: 'overview' },
{ label: 'navigation.project.metadata', routerLink: 'metadata' },
{ label: 'navigation.project.files', routerLink: 'files' },
{
label: 'navigation.project.registrations',
routerLink: 'registrations',
},
],
},
];
16 changes: 16 additions & 0 deletions src/app/core/helpers/i18n.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TranslateLoader, TranslateModuleConfig } from '@ngx-translate/core';
import { HttpClient } from '@angular/common/http';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

function httpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

export const provideTranslation = (): TranslateModuleConfig => ({
defaultLanguage: 'en',
loader: {
provide: TranslateLoader,
useFactory: httpLoaderFactory,
deps: [HttpClient],
},
});
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
<section class="forgot-password-container" [class.mobile]="isMobile()">
<h2>Forgot Your Password?</h2>
<p>Enter your email address and we'll send a link to reset your password</p>
<h2>{{ "auth.forgotPassword.title" | translate }}</h2>
<p>{{ "auth.forgotPassword.description" | translate }}</p>

<form [formGroup]="forgotPasswordForm" (ngSubmit)="onSubmit()">
<label for="email">Email</label>
<label for="email">{{ "auth.common.email" | translate }}</label>
<input
class="email-input"
id="email"
type="email"
pInputText
formControlName="email"
placeholder="email@example.com"
[placeholder]="'auth.common.emailPlaceholder' | translate"
autocomplete="off"
/>

<p-button
class="btn-full-width"
type="submit"
label="Reset Password"
[label]="'auth.forgotPassword.submit' | translate"
[disabled]="!forgotPasswordForm.valid"
></p-button>
</form>
Expand All @@ -27,7 +27,7 @@ <h2>Forgot Your Password?</h2>
<p-message
[severity]="message()?.severity"
closable="true"
[text]="message()?.content"
[text]="message()!.content | translate"
(onClose)="onCloseMessage()"
/>
}
Expand Down
Loading