Skip to content
Snippets Groups Projects
Unverified Commit a7fb2d1e authored by Oliver Günther's avatar Oliver Günther
Browse files

Error handling in frontend module

parent 2e9fcafa
No related branches found
No related tags found
No related merge requests found
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2022 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
en:
js:
souvap:
central_navigation:
loading_error: "Failed to load central navigation"
<ng-container *ngIf="active$ | async">
<ng-container *ngIf="(navigationGroups$ | async) as groups; else loadingTemplate">
<ng-container *ngIf="(navigationGroups$ | async) as groups; else loadingOrError">
<ul
*ngFor="let group of groups"
class="op-souvap-navigation--group"
......@@ -27,13 +27,22 @@
</ul>
</ng-container>
</ng-container>
<ng-template #loadingTemplate>
<op-content-loader
class="op-add-existing-pane--loading"
viewBox="0 0 200 70"
<ng-template #loadingOrError>
<span
*ngIf="(loadingError$ | async) as error; else loading"
class="op-menu--item-action"
>
<svg:rect x="0" y="0" width="100%" height="20" rx="1"/>
<svg:rect x="0" y="24" width="100%" height="20" rx="1"/>
<svg:rect x="0" y="48" width="100%" height="20" rx="1"/>
</op-content-loader>
<span class="spot-icon spot-icon_warning"></span>
{{ text.error }}
</span>
<ng-template #loading>
<op-content-loader
class="op-add-existing-pane--loading"
viewBox="0 0 200 70"
>
<svg:rect x="0" y="0" width="100%" height="20" rx="1"/>
<svg:rect x="0" y="24" width="100%" height="20" rx="1"/>
<svg:rect x="0" y="48" width="100%" height="20" rx="1"/>
</op-content-loader>
</ng-template>
</ng-template>
......@@ -5,12 +5,16 @@ import {
HostBinding,
} from '@angular/core';
import { TopMenuService } from 'core-app/core/top-menu/top-menu.service';
import { map } from 'rxjs/operators';
import {
catchError,
map,
} from 'rxjs/operators';
import { CentralNavigationService } from 'core-app/features/plugins/linked/openproject-souvap/central-navigation/central-navigation.service';
import {
DomSanitizer,
SafeUrl,
} from '@angular/platform-browser';
import { I18nService } from 'core-app/core/i18n/i18n.service';
export const souvapCentralNavigationSelector = 'op-souvap-central-navigation';
......@@ -23,7 +27,9 @@ export const souvapCentralNavigationSelector = 'op-souvap-central-navigation';
export class CentralNavigationComponent {
@HostBinding('class.op-souvap-navigation') className = true;
text:string;
text = {
error: this.I18n.t('js.souvap.central_navigation.loading_error'),
};
active$ = this
.topMenuService
......@@ -34,11 +40,14 @@ export class CentralNavigationComponent {
navigationGroups$ = this.centralNavigationService.navigationGroups$;
loadingError$ = this.centralNavigationService.loadingError$;
constructor(
private topMenuService:TopMenuService,
private elementRef:ElementRef,
private centralNavigationService:CentralNavigationService,
private sanitizer:DomSanitizer,
private I18n:I18nService,
) {}
iconURL(url:string):SafeUrl {
......
import { IApplicationGroup } from 'core-app/features/plugins/linked/openproject-souvap/central-navigation/central-navigation.model';
import { shareReplay } from 'rxjs/operators';
import {
catchError,
shareReplay,
} from 'rxjs/operators';
import { TopMenuService } from 'core-app/core/top-menu/top-menu.service';
import { Injectable } from '@angular/core';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { HttpClient } from '@angular/common/http';
import {
HttpClient,
HttpErrorResponse,
} from '@angular/common/http';
import {
of,
Subject,
} from 'rxjs';
@Injectable({ providedIn: 'root' })
export class CentralNavigationService {
private url = this.pathHelper.api.v3.apiV3Base + '/linked_applications';
loadingError$ = new Subject<boolean>();
navigationGroups$ = this
.http
.get<IApplicationGroup[]>(this.url)
.pipe(
catchError((err:HttpErrorResponse) => {
console.error(err.message);
this.loadingError$.next(true);
return of();
}),
shareReplay(1),
);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment

Consent

On this website, we use the web analytics service Matomo to analyze and review the use of our website. Through the collected statistics, we can improve our offerings and make them more appealing for you. Here, you can decide whether to allow us to process your data and set corresponding cookies for these purposes, in addition to technically necessary cookies. Further information on data protection—especially regarding "cookies" and "Matomo"—can be found in our privacy policy. You can withdraw your consent at any time.