Skip to content

Commit 3ce619a

Browse files
committed
fix merge conflcts
2 parents bba5bfb + a933d9d commit 3ce619a

44 files changed

Lines changed: 316 additions & 56 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.9.1 (2026-04-28)
6+
===================
7+
8+
* Hotfix to add alias for ip addresses, redux
9+
10+
26.9.0 (2026-04-28)
11+
===================
12+
13+
* Misc. improvements and bug fixes
14+
15+
26.8.2 (2026-04-20)
16+
===================
17+
18+
* Hotfix to add alias for ip addresses, again
19+
20+
26.8.1 (2026-04-20)
21+
===================
22+
23+
* Hotfix to add alias for ip addresses
24+
25+
26.8.0 (2026-04-16)
26+
===================
27+
28+
* Angular upgrade
29+
530
26.7.0 (2026-04-08)
631
===================
732

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.7.0",
3+
"version": "26.9.1",
44
"scripts": {
55
"ng": "ng",
66
"analyze-bundle": "ng build --configuration=analyze-bundle && source-map-explorer dist/**/*.js --no-border-checks",

src/app/core/components/layout/layout.component.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919

2020
<osf-footer></osf-footer>
2121
</div>
22+
23+
@if (isMaintenanceMode()) {
24+
<section class="maintenance-overlay font-bold text-xl flex flex-column align-items-center justify-content-center">
25+
<p>{{ 'maintenance.title' | translate }}</p>
26+
<p>{{ 'maintenance.message' | translate }}</p>
27+
</section>
28+
}
2229
</main>
2330

2431
<p-confirm-dialog

src/app/core/components/layout/layout.component.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,10 @@
8484
}
8585
}
8686
}
87+
88+
.maintenance-overlay {
89+
position: fixed;
90+
inset: 0;
91+
z-index: 2000;
92+
background: var(--white);
93+
}

src/app/core/components/layout/layout.component.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { MockComponents, MockProvider } from 'ng-mocks';
22

3-
import { ConfirmationService } from 'primeng/api';
43
import { ConfirmDialog } from 'primeng/confirmdialog';
54

65
import { BehaviorSubject } from 'rxjs';
76

87
import { ComponentFixture, TestBed } from '@angular/core/testing';
98

9+
import { MaintenanceModeService } from '@core/services/maintenance-mode.service';
1010
import { IS_MEDIUM, IS_WEB } from '@osf/shared/helpers/breakpoints.tokens';
1111

1212
import { provideOSFCore } from '@testing/osf.testing.provider';
13+
import { MaintenanceModeServiceMock } from '@testing/providers/maintenance-mode.service.mock';
1314

1415
import { BreadcrumbComponent } from '../breadcrumb/breadcrumb.component';
1516
import { FooterComponent } from '../footer/footer.component';
@@ -47,7 +48,7 @@ describe('LayoutComponent', () => {
4748
provideOSFCore(),
4849
MockProvider(IS_WEB, isWebSubject),
4950
MockProvider(IS_MEDIUM, isMediumSubject),
50-
MockProvider(ConfirmationService),
51+
MockProvider(MaintenanceModeService, MaintenanceModeServiceMock.simple()),
5152
],
5253
});
5354

src/app/core/components/layout/layout.component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
66
import { toSignal } from '@angular/core/rxjs-interop';
77
import { RouterOutlet } from '@angular/router';
88

9+
import { MaintenanceModeService } from '@core/services/maintenance-mode.service';
910
import { ScrollTopOnRouteChangeDirective } from '@osf/shared/directives/scroll-top.directive';
1011
import { IS_MEDIUM, IS_WEB } from '@osf/shared/helpers/breakpoints.tokens';
1112

@@ -35,6 +36,9 @@ import { TopnavComponent } from '../topnav/topnav.component';
3536
changeDetection: ChangeDetectionStrategy.OnPush,
3637
})
3738
export class LayoutComponent {
39+
private readonly maintenanceModeService = inject(MaintenanceModeService);
40+
3841
isWeb = toSignal(inject(IS_WEB));
3942
isMedium = toSignal(inject(IS_MEDIUM));
43+
isMaintenanceMode = this.maintenanceModeService.isActive;
4044
}

src/app/core/components/osf-banners/maintenance-banner/maintenance-banner.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
styleClass="w-full"
55
icon="pi pi-info-circle"
66
[severity]="maintenance()?.severity"
7-
[text]="maintenance()?.message"
87
[closable]="true"
98
(onClose)="dismiss()"
109
>
10+
{{ maintenance()?.message }}
1111
</p-message>
1212
}

src/app/core/interceptors/error.interceptor.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@ import { Router } from '@angular/router';
99

1010
import { SENTRY_TOKEN } from '@core/provider/sentry.provider';
1111
import { AuthService } from '@core/services/auth.service';
12+
import { MaintenanceModeService } from '@core/services/maintenance-mode.service';
1213
import { ToastService } from '@osf/shared/services/toast.service';
1314
import { ViewOnlyLinkHelperService } from '@osf/shared/services/view-only-link-helper.service';
1415

1516
import { provideOSFCore } from '@testing/osf.testing.provider';
1617
import { AuthServiceMock, AuthServiceMockType } from '@testing/providers/auth-service.mock';
1718
import { LoaderServiceMock, provideLoaderServiceMock } from '@testing/providers/loader-service.mock';
19+
import {
20+
MaintenanceModeServiceMock,
21+
MaintenanceModeServiceMockType,
22+
} from '@testing/providers/maintenance-mode.service.mock';
1823
import { RouterMockBuilder, RouterMockType } from '@testing/providers/router-provider.mock';
1924
import { SentryMock, SentryMockType } from '@testing/providers/sentry-provider.mock';
2025
import { ToastServiceMock, ToastServiceMockType } from '@testing/providers/toast-provider.mock';
@@ -28,6 +33,7 @@ describe('errorInterceptor', () => {
2833
let toastServiceMock: ToastServiceMockType;
2934
let loaderServiceMock: LoaderServiceMock;
3035
let authServiceMock: AuthServiceMockType;
36+
let maintenanceModeServiceMock: MaintenanceModeServiceMockType;
3137
let viewOnlyHelperMock: ViewOnlyLinkHelperMockType;
3238
let sentryMock: SentryMockType;
3339

@@ -36,6 +42,7 @@ describe('errorInterceptor', () => {
3642
toastServiceMock = ToastServiceMock.simple();
3743
loaderServiceMock = new LoaderServiceMock();
3844
authServiceMock = AuthServiceMock.simple();
45+
maintenanceModeServiceMock = MaintenanceModeServiceMock.simple();
3946
viewOnlyHelperMock = ViewOnlyLinkHelperMock.simple(viewOnly);
4047
sentryMock = SentryMock.simple();
4148

@@ -46,6 +53,7 @@ describe('errorInterceptor', () => {
4653
MockProvider(Router, router),
4754
MockProvider(ToastService, toastServiceMock),
4855
MockProvider(AuthService, authServiceMock),
56+
MockProvider(MaintenanceModeService, maintenanceModeServiceMock),
4957
MockProvider(ViewOnlyLinkHelperService, viewOnlyHelperMock),
5058
MockProvider(PLATFORM_ID, platformId),
5159
{ provide: SENTRY_TOKEN, useValue: sentryMock },
@@ -156,4 +164,21 @@ describe('errorInterceptor', () => {
156164
expect(loaderServiceMock.hide).toHaveBeenCalled();
157165
expect(toastServiceMock.showError).not.toHaveBeenCalled();
158166
});
167+
168+
it('should activate maintenance mode on 503 maintenance response', async () => {
169+
setup('browser', false);
170+
const request = createRequest('/api/v2/');
171+
const error = new HttpErrorResponse({
172+
status: 503,
173+
error: { meta: { maintenance_mode: true } },
174+
url: request.url,
175+
});
176+
177+
const caught = await runInterceptor(request, error);
178+
179+
expect(caught?.status).toBe(503);
180+
expect(maintenanceModeServiceMock.activate).toHaveBeenCalled();
181+
expect(loaderServiceMock.hide).toHaveBeenCalled();
182+
expect(toastServiceMock.showError).not.toHaveBeenCalled();
183+
});
159184
});

src/app/core/interceptors/error.interceptor.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import { inject, PLATFORM_ID } from '@angular/core';
77
import { Router } from '@angular/router';
88

99
import { ERROR_MESSAGES } from '@core/constants/error-messages';
10+
import { MaintenanceResponse } from '@core/models/maintenance-response.model';
1011
import { SENTRY_TOKEN } from '@core/provider/sentry.provider';
1112
import { AuthService } from '@core/services/auth.service';
13+
import { MaintenanceModeService } from '@core/services/maintenance-mode.service';
1214
import { LoaderService } from '@osf/shared/services/loader.service';
1315
import { ToastService } from '@osf/shared/services/toast.service';
1416
import { ViewOnlyLinkHelperService } from '@osf/shared/services/view-only-link-helper.service';
@@ -20,6 +22,7 @@ export const errorInterceptor: HttpInterceptorFn = (req, next) => {
2022
const loaderService = inject(LoaderService);
2123
const router = inject(Router);
2224
const authService = inject(AuthService);
25+
const maintenanceModeService = inject(MaintenanceModeService);
2326
const sentry = inject(SENTRY_TOKEN);
2427
const platformId = inject(PLATFORM_ID);
2528
const viewOnlyHelper = inject(ViewOnlyLinkHelperService);
@@ -43,6 +46,17 @@ export const errorInterceptor: HttpInterceptorFn = (req, next) => {
4346
}
4447

4548
const serverErrorRegex = /5\d{2}/;
49+
const maintenanceResponse = error.error as MaintenanceResponse | null;
50+
51+
const maintenanceMode = error.status === 503 && maintenanceResponse?.meta?.maintenance_mode === true;
52+
53+
if (maintenanceMode) {
54+
loaderService.hide();
55+
if (isPlatformBrowser(platformId)) {
56+
maintenanceModeService.activate();
57+
}
58+
return throwError(() => error);
59+
}
4660

4761
if (serverErrorRegex.test(error.status.toString())) {
4862
errorMessage = error.error.message || 'common.errorMessages.serverError';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface MaintenanceResponse {
2+
meta?: {
3+
maintenance_mode?: boolean;
4+
};
5+
}

0 commit comments

Comments
 (0)