Skip to content

Commit 79e7732

Browse files
authored
Merge pull request #909 from nsemets/fix/develop-merge
Merge develop into feature/pbs-26-2
2 parents fe1fc61 + b37bb83 commit 79e7732

59 files changed

Lines changed: 936 additions & 290 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,31 @@
22

33
We follow the CalVer (https://calver.org/) versioning scheme: YY.MINOR.MICRO.
44

5+
26.5.0 (2026-02-26)
6+
===================
7+
8+
* Config updates to enable Angular SSR
9+
10+
26.4.0 (2026-02-26)
11+
===================
12+
13+
* Search and fetch funder ids from ROR instead of CrossRef
14+
15+
26.3.1 (2026-02-25)
16+
===================
17+
18+
* Hotfix to prevent 403 error when fetching metadata from causing a redirect
19+
20+
26.3.0 (2026-02-24)
21+
===================
22+
23+
* FAIR Signposting
24+
25+
26.2.1 (2026-02-03)
26+
===================
27+
28+
* Hotfix for navigation translations and contributor search
29+
530
26.2.0 (2026-01-29)
631
===================
732

Dockerfile

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,37 @@
1-
# Build
2-
FROM node:22-alpine AS build
3-
1+
# Dependencies stage
2+
FROM node:22-alpine AS deps
43
WORKDIR /app
5-
64
COPY package*.json ./
7-
RUN npm install
5+
RUN npm ci --no-audit --no-fund
86

7+
# Build stage (SSR build output)
8+
FROM deps AS build
99
COPY . .
10+
RUN NG_BUILD_OPTIMIZE_CHUNKS=1 npx ng build --configuration=ssr --verbose
1011

11-
RUN npm link @angular/cli
12-
RUN NG_BUILD_OPTIMIZE_CHUNKS=1 ng build --verbose
13-
14-
# Dist
15-
FROM node:22-alpine AS dist
16-
17-
WORKDIR /code
18-
19-
COPY --from=build /app/dist /code/dist
20-
21-
# SSR
22-
FROM node:22-alpine AS ssr
23-
12+
# SSR runtime stage
13+
FROM build AS ssr
2414
WORKDIR /app
25-
26-
COPY package*.json ./
27-
RUN npm install
28-
29-
COPY . .
30-
31-
RUN npm link @angular/cli
32-
RUN NG_BUILD_OPTIMIZE_CHUNKS=1 ng build --configuration=ssr --verbose
33-
34-
RUN npm ci --omit=dev --ignore-scripts --no-audit --no-fund
35-
15+
RUN npm prune --omit=dev --no-audit --no-fund
3616
EXPOSE 4000
37-
3817
ENV PORT=4000
39-
4018
CMD ["node", "dist/osf/server/server.mjs"]
4119

42-
# Dev - run only
43-
FROM build AS dev
20+
# Static dist artifact stage
21+
FROM node:22-alpine AS dist
22+
WORKDIR /code
23+
COPY --from=build /app/dist /code/dist
4424

25+
# Dev server stage
26+
FROM deps AS dev
27+
COPY . .
4528
EXPOSE 4200
29+
CMD ["npx", "ng", "serve", "--host", "0.0.0.0"]
4630

47-
CMD ["ng", "serve"]
48-
49-
# Local Development - coding
31+
# Local development stage
5032
FROM node:22-alpine AS local-dev
5133
WORKDIR /app
52-
53-
# Install deps in the image (kept in container)
5434
COPY package*.json ./
55-
# COPY package-lock.docker.json ./package-lock.json
5635
RUN npm ci --no-audit --no-fund
57-
58-
# Expose Angular dev server
5936
EXPOSE 4200
37+
CMD ["npx", "ng", "serve", "--host", "0.0.0.0"]

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "osf",
3-
"version": "26.2.0",
3+
"version": "26.5.0",
44
"scripts": {
55
"ng": "ng",
66
"analyze-bundle": "ng build --configuration=analyze-bundle && source-map-explorer dist/**/*.js --no-border-checks",

src/@types/ace-builds.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module 'ace-builds/src-noconflict/ext-language_tools';

src/app/app.config.server.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,42 @@ import { ApplicationConfig, mergeApplicationConfig } from '@angular/core';
22
import { provideServerRendering } from '@angular/platform-server';
33
import { provideServerRouting } from '@angular/ssr';
44

5+
import { SSR_CONFIG } from '@core/constants/ssr-config.token';
6+
import { ConfigModel } from '@core/models/config.model';
7+
58
import { appConfig } from './app.config';
69
import { serverRoutes } from './app.routes.server';
710

11+
import { existsSync, readFileSync } from 'node:fs';
12+
import { dirname, resolve } from 'node:path';
13+
import { fileURLToPath } from 'node:url';
14+
15+
function loadSsrConfig(): ConfigModel {
16+
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
17+
const configPath = resolve(serverDistFolder, '../browser/assets/config/config.json');
18+
19+
let config = {} as ConfigModel;
20+
21+
if (existsSync(configPath)) {
22+
try {
23+
config = JSON.parse(readFileSync(configPath, 'utf-8'));
24+
} catch {
25+
config = {} as ConfigModel;
26+
}
27+
}
28+
29+
return {
30+
...config,
31+
throttleToken: process.env['THROTTLE_TOKEN'] || '',
32+
} as ConfigModel;
33+
}
34+
835
const serverConfig: ApplicationConfig = {
9-
providers: [provideServerRendering(), provideServerRouting(serverRoutes)],
36+
providers: [
37+
provideServerRendering(),
38+
provideServerRouting(serverRoutes),
39+
{ provide: SSR_CONFIG, useFactory: loadSsrConfig },
40+
],
1041
};
1142

1243
export const config = mergeApplicationConfig(appConfig, serverConfig);

src/app/app.routes.server.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ export const serverRoutes: ServerRoute[] = [
133133
path: ':id/overview',
134134
renderMode: RenderMode.Server,
135135
},
136+
{
137+
path: ':id/metadata/:recordId',
138+
renderMode: RenderMode.Server,
139+
},
140+
{
141+
path: ':id/wiki',
142+
renderMode: RenderMode.Server,
143+
},
136144
{
137145
path: ':id/files/**',
138146
renderMode: RenderMode.Server,

src/app/core/components/nav-menu/nav-menu.component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@ export class NavMenuComponent {
4444
private readonly isAuthenticated = select(UserSelectors.isAuthenticated);
4545
private readonly currentResource = select(CurrentResourceSelectors.getCurrentResource);
4646
private readonly provider = select(ProviderSelectors.getCurrentProvider);
47+
private readonly translationsReady = toSignal(this.translateService.stream('navigation.overview'));
4748

4849
readonly actions = createDispatchMap({ getResourceDetails: GetResourceDetails });
4950

5051
readonly mainMenuItems = computed(() => {
52+
this.translationsReady();
5153
const isAuthenticated = this.isAuthenticated();
5254
const filtered = filterMenuItems(MENU_ITEMS, isAuthenticated);
5355

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { InjectionToken } from '@angular/core';
2+
3+
import { ConfigModel } from '@core/models/config.model';
4+
5+
export const SSR_CONFIG = new InjectionToken<ConfigModel>('SSR_CONFIG');

src/app/core/helpers/i18n.helper.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
import { TranslateLoader, TranslateModuleConfig } from '@ngx-translate/core';
22
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
33

4+
import { isPlatformServer } from '@angular/common';
45
import { HttpClient } from '@angular/common/http';
6+
import { inject, PLATFORM_ID } from '@angular/core';
7+
8+
import { ENVIRONMENT } from '@core/provider/environment.provider';
59

610
function httpLoaderFactory(http: HttpClient): TranslateHttpLoader {
7-
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
11+
const platformId = inject(PLATFORM_ID);
12+
const environment = inject(ENVIRONMENT);
13+
const basePrefix = '/assets/i18n/';
14+
const webUrl = environment.webUrl?.replace(/\/+$/, '') ?? '';
15+
const prefix = isPlatformServer(platformId) && webUrl ? `${webUrl}${basePrefix}` : basePrefix;
16+
17+
return new TranslateHttpLoader(http, prefix, '.json');
818
}
919

1020
export const provideTranslation = (): TranslateModuleConfig => ({

0 commit comments

Comments
 (0)