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
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ npm start
## Usage
Reactome has a wide range of features, to explore more of Reactome or get more information visit [the documentation page](https://reactome.org/documentation) or see the ````/documentation```` folder in the root directory.

## Configuration

The application configuration is centralized in TypeScript files under `projects/website-angular/src/config/`. Key configurations include:

- `config.ts`: App-level settings like version, base URLs, and feature flags.
- `environments.ts`: Environment-specific settings (development, production, etc.).
- `api-routes.ts`: API endpoint URLs derived from the current environment.
- `features.ts`: Feature flags for toggling functionality.
- `external-links.ts`: External links, including dynamically constructed release notes.

To update configuration values, edit the respective TS files. For environment-specific builds, consider using Angular's file replacements in `angular.json`.

## Additional Resources

## LICENSE
[Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { ENVIRONMENTS } from '../../../website-angular/src/config/environments';

const env = ENVIRONMENTS.development;

export const environment = {
production: true,
host: "../..", // For go back from /beta/PathwayBrowser
s3: "https://download.reactome.org",
gsaServer: "dev",
gtagId: "G-96F1EYHQR3",
preferS3: false,
host: env.host,
s3: env.s3,
gsaServer: env.gsaServer,
gtagId: env.gtagId,
preferS3: env.preferS3
};

export const CONTENT_SERVICE = `${environment.host}/ContentService`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { ENVIRONMENTS } from '../../../website-angular/src/config/environments';

const env = ENVIRONMENTS.production;

export const environment = {
production: true,
host: "../..", // For go back from /beta/PathwayBrowser
s3: "https://download.reactome.org",
gsaServer: "production",
gtagId: "G-EDHZ92GXZP",
preferS3: true,

host: env.host,
s3: env.s3,
gsaServer: env.gsaServer,
gtagId: env.gtagId,
preferS3: env.preferS3
};

export const CONTENT_SERVICE = `${environment.host}/ContentService`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
import { MatIcon } from "@angular/material/icon";
import {NavLink} from '../../types/link';
import { mapNavOptions } from '../../utils/nav-options-mapper';
import { EXTERNAL_LINKS } from '../../config/external-links'; // NEW import

@Component({
selector: 'app-copyright-footer',
Expand All @@ -19,9 +20,7 @@ export class copyrightFooterComponent implements OnInit {
}

loadExternalLinks() {
// Load external links from the JSON file
import('../../config/external-links.json').then((data) => {
this.externalLinks = mapNavOptions(data.default);
});
// Use the new TS constant instead of dynamic JSON import
this.externalLinks = EXTERNAL_LINKS as unknown as Record<string, NavLink>;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Component } from '@angular/core';
import { CarouselComponent } from "../../reactome-components/carousel/carousel.component";
import { ButtonComponent } from "../../reactome-components/button/button.component";
import { MatIcon } from "@angular/material/icon";
import { CarouselComponent } from '../../reactome-components/carousel/carousel.component';
import { ButtonComponent } from '../../reactome-components/button/button.component';
import { MatIcon } from '@angular/material/icon';
import { mapNavOptions } from '../../../utils/nav-options-mapper';
import { ExternalLink, NavOption } from '../../../types/link';
import { EXTERNAL_LINKS } from '../../../config/external-links'; // NEW import

@Component({
selector: 'app-home-help',
Expand Down Expand Up @@ -31,10 +32,9 @@ export class HomeHelpComponent {
}

loadExternalLinks() {
import('../../../config/external-links.json').then((data) => {
this.externalLinks = mapNavOptions(data.default);
this.releaseNotesLink = this.externalLinks['releaseNotes']?.link || '';
this.feedbackLink = this.externalLinks['feedback']?.link || '';
});
// Use the new TS constant instead of dynamic JSON import
this.externalLinks = EXTERNAL_LINKS as unknown as Record<string, ExternalLink>;
this.releaseNotesLink = this.externalLinks['releaseNotes']?.link || '';
this.feedbackLink = this.externalLinks['feedback']?.link || '';
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from '@angular/core';
import {ExternalLink} from '../../../types/link';
import { mapNavOptions } from '../../../utils/nav-options-mapper';
import { EXTERNAL_LINKS } from '../../../config/external-links'; // NEW import

@Component({
selector: 'app-home-related',
Expand All @@ -17,8 +18,7 @@ export class HomeRelatedComponent {
}

loadExternalLinks() {
import('../../../config/external-links.json').then((data) => {
this.externalLinks = mapNavOptions(data.default);
});
// Use the new TS constant instead of dynamic JSON import
this.externalLinks = EXTERNAL_LINKS as unknown as Record<string, ExternalLink>;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, inject } from '@angular/core';
import { MatIcon } from "@angular/material/icon";
import { CarouselComponent } from "../../reactome-components/carousel/carousel.component";
import { StatsService } from '../../../services/stats.service';
import { APP_CONFIG } from '../../../config/config'; // NEW import

interface Stats {
human_pathways: number;
Expand Down Expand Up @@ -39,11 +40,10 @@ export class HomeStatsComponent {
}

getVersionAndDate () {
import('../../../config/config.json').then((data) => {
this.version = data.default.version.releaseNumber;
this.releaseDate = new Date(data.default.version.releaseDate);
this.fetchStats();
});
// Use APP_CONFIG instead of dynamic JSON import
this.version = APP_CONFIG.version.releaseNumber;
this.releaseDate = new Date(APP_CONFIG.version.releaseDate);
this.fetchStats();
}

fetchStats () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from '@angular/core';
import {ExternalLink, NavOption} from '../../../types/link';
import { mapNavOptions } from '../../../utils/nav-options-mapper';
import { EXTERNAL_LINKS } from '../../../config/external-links'; // NEW import

@Component({
selector: 'app-home-why-reactome',
Expand All @@ -19,9 +20,8 @@ export class HomeWhyReactomeComponent {
}

loadExternalLinks() {
import('../../../config/external-links.json').then((data) => {
this.externalLinks = mapNavOptions(data.default);
});
// Use the new TS constant instead of dynamic JSON import
this.externalLinks = EXTERNAL_LINKS as unknown as Record<string, ExternalLink>;
}

loadNavOptions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { FormsModule } from '@angular/forms';
import { mapNavOptions } from '../../utils/nav-options-mapper';
import { NavLink, NavOption } from '../../types/link';
import { DarkService } from '../../../../pathway-browser/src/app/services/dark.service';
import { APP_CONFIG } from '../../config/config'; // NEW import

@Component({
standalone: true,
Expand Down Expand Up @@ -43,12 +44,9 @@ export class NavigationBarComponent implements OnInit, AfterViewInit {
}

loadNavOptions() {
Promise.all([
import('../../config/nav-options.json'),
import('../../config/config.json')
]).then(([navData, configData]) => {
import('../../config/nav-options.json').then((navData) => {
this.navOptions = mapNavOptions(navData.default);
this.resolveExternalLinks(configData.default.baseUrl);
this.resolveExternalLinks(APP_CONFIG.baseUrl);
});
}

Expand Down
14 changes: 14 additions & 0 deletions projects/website-angular/src/config/api-routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { getEnv } from './environments';

const env = getEnv(process.env['APP_ENV'] || (typeof window !== 'undefined' && (window as any).__APP_ENV) || undefined);

export const API_ROUTES = {
CONTENT_SERVICE: `${env.host}/ContentService`,
ANALYSIS_SERVICE: `${env.host}/AnalysisService`,
EXPERIMENT_SERVICE: `${env.host}/experiment`,
RESTFUL_API: `${env.host}/ReactomeRESTfulAPI/RESTfulWS`,
DOWNLOAD: `${env.host}/download/current`,
OVERLAYS: `${env.host}/overlays`,
CONTENT_DETAIL: `${env.host}/content/detail`,
CONTENT_QUERY: `${env.host}/content/query`
} as const;
29 changes: 29 additions & 0 deletions projects/website-angular/src/config/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const APP_CONFIG = {
// app-level version info
version: {
label: 'V95',
releaseNumber: '95',
releaseDate: '2025-12-09'
},

// canonical site base / download base (choose prod by default)
baseUrl: 'https://reactome.org',
downloadUrl: 'https://download.reactome.org',

// pathway browser config
pathwayBrowser: {
stablePath: '/PathwayBrowser',
betaPath: '/beta/PathwayBrowser',
useBeta: false // default; can be toggled per env or flag
},

// release notes (can be computed by the app using version.releaseNumber)
// if you'd like to point at a specific article, set here; otherwise use derived URIs
releaseNotesPath: '/about/news',

// default flags (feature flags)
features: {
betaPathwayBrowser: false,
useNewAnalysisService: false
}
} as const;
43 changes: 43 additions & 0 deletions projects/website-angular/src/config/environments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export type EnvName = 'development' | 'production' | 'local' | 'github' | 'remote';

export const ENVIRONMENTS: Record<EnvName, { host: string; s3: string; gsaServer: string; gtagId?: string; preferS3?: boolean }> = {
development: {
host: 'https://dev.reactome.org',
s3: 'https://download.reactome.org',
gsaServer: 'dev',
gtagId: 'G-96F1EYHQR3',
preferS3: false
},
production: {
host: 'https://reactome.org',
s3: 'https://download.reactome.org',
gsaServer: 'production',
gtagId: 'G-EDHZ92GXZP',
preferS3: true
},
local: {
host: 'http://localhost:4200',
s3: 'https://download.reactome.org',
gsaServer: 'dev',
preferS3: false
},
github: {
host: '../..',
s3: 'https://download.reactome.org',
gsaServer: 'production',
preferS3: true
},
remote: {
host: 'https://dev.reactome.org',
s3: 'https://download.reactome.org',
gsaServer: 'dev',
preferS3: false
}
} as const;

// Helper: pick environment at runtime (fallback to production)
export function getEnv(envName?: string) {
if (!envName) return ENVIRONMENTS.production;
const key = envName as EnvName;
return ENVIRONMENTS[key] ?? ENVIRONMENTS.production;
}
20 changes: 20 additions & 0 deletions projects/website-angular/src/config/external-links.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { APP_CONFIG } from './config';

export const EXTERNAL_LINKS = {
twitter: { label: 'Twitter', link: 'https://twitter.com/Reactome' },
facebook: { label: 'Facebook', link: 'https://www.facebook.com/reactome' },
youtube: { label: 'Youtube', link: 'https://www.youtube.com/@Reactome' },
github: { label: 'GitHub', link: 'https://github.com/reactome' },
bluesky: { label: 'Bluesky', link: 'https://bsky.app/profile/reactome.org' },
linkedin: { label: 'LinkedIn', link: 'https://ca.linkedin.com/company/reactome-group' },
elixir: { label: 'elixir', link: 'https://elixir-europe.org/platforms/data/core-data-resources' },
gcdr: { label: 'GCDR', link: 'https://globalbiodata.org/scientific-activities/global-core-biodata-resources/' },
coretrustseal: { label: 'CoreTrustSeal', link: 'https://www.coretrustseal.org/' },
ebi: { label: 'EBI', link: 'http://www.ebi.ac.uk/' },
nyu: { label: 'NYU', link: 'https://med.nyu.edu/' },
ohsu: { label: 'OHSU', link: 'http://www.ohsu.edu/' },
oicr: { label: 'OICR', link: 'https://oicr.on.ca/' },
// dynamically construct release notes link using APP_CONFIG
releaseNotes: { label: 'Release Notes', link: `${APP_CONFIG.baseUrl}${APP_CONFIG.releaseNotesPath}` },
feedback: { label: 'Feedback', link: 'https://forms.gle/TPBxaWnnVLLZj66p8' }
} as const;
5 changes: 5 additions & 0 deletions projects/website-angular/src/config/features.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const FEATURES = {
betaPathwayBrowser: false,
useNewAnalysisService: false,
// add other feature flags here and flip them by editing this file or via an external mechanism
} as const;
18 changes: 6 additions & 12 deletions projects/website-angular/src/services/stats.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Injectable, inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Observable, map, catchError, of, timeout } from 'rxjs';
import { APP_CONFIG } from '../config/config'; // NEW import

export interface ReactomeStats {
pathways: number;
Expand All @@ -26,30 +27,23 @@ export class StatsService {
private isBrowser = isPlatformBrowser(this.platformId);

/**
* Get the current Reactome version
* Get the current Reactome version from APP_CONFIG
*/
async getVersion(): Promise<string> {
let version = await import('../config/config.json').then(
(data) => data.default.version.releaseNumber
);
return version;
return APP_CONFIG.version.releaseNumber;
}

/**
* Get the download base URL
* Get the download base URL from APP_CONFIG
*/
async getDownloadBaseUrl(): Promise<string> {
let downloadUrl = await import('../config/config.json').then(
(data) => data.default.downloadurl
);

return downloadUrl;
return APP_CONFIG.downloadUrl;
}

/**
* Fetch stats from the S3/CloudFront download directory
*/
async getStats():Promise<Observable<ReactomeStats>> {
async getStats(): Promise<Observable<ReactomeStats>> {
const defaultStats: ReactomeStats = {
pathways: 0,
reactions: 0,
Expand Down
Loading