Skip to content

Commit

Permalink
ufal/fe-license-static-pages-are-missing (#380)
Browse files Browse the repository at this point in the history
* Added static files and redirection

* Html content is loaded from the static file and rendered in the component.

* The html file content is showed in the `static/` route with the error page. The translation works.

* Created routing for the `licenses` page and changed administrator license table to `licenses/manage-table` path

* Show all licenses data.

* All licenses are filtered by license label - PUB, ACA, RES

* Added loading bar

* Added redirect from license selector

* Fixed tests.

* Refactoring

* Fixed lint error - unused import

* Added docs and translations.

* Removed accidentally added semicolon.

* Added simple test if the html file content will be loaded.
milanmajchrak authored Oct 16, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 1e4ea47 commit 6f146c2
Showing 61 changed files with 12,194 additions and 14 deletions.
6 changes: 6 additions & 0 deletions src/app/app-routing-paths.ts
Original file line number Diff line number Diff line change
@@ -130,6 +130,12 @@ export function getLicensesModulePath() {
return `/${LICENSES_MODULE_PATH}`;
}


export const LICENSES_MANAGE_TABLE_PATH = 'manage-table';
export function getLicensesManageTablePath() {
return `/${LICENSES_MANAGE_TABLE_PATH}`;
}

export const CONTRACT_PAGE_MODULE_PATH = 'contract';
export function getLicenseContractPagePath() {
return `/${CONTRACT_PAGE_MODULE_PATH}`;
8 changes: 6 additions & 2 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -43,6 +43,7 @@ import { ServerCheckGuard } from './core/server-check/server-check.guard';
import { MenuResolver } from './menu.resolver';
import { ThemedPageErrorComponent } from './page-error/themed-page-error.component';
import { HANDLE_TABLE_MODULE_PATH } from './handle-page/handle-page-routing-paths';
import { STATIC_PAGE_PATH } from './static-page/static-page-routing-paths';

@NgModule({
imports: [
@@ -247,7 +248,6 @@ import { HANDLE_TABLE_MODULE_PATH } from './handle-page/handle-page-routing-path
{
path: LICENSES_MODULE_PATH,
loadChildren: () => import('./clarin-licenses/clarin-license.module').then((m) => m.ClarinLicenseModule),
canActivate: [SiteAdministratorGuard],
},
{
path: CONTRACT_PAGE_MODULE_PATH,
@@ -260,6 +260,10 @@ import { HANDLE_TABLE_MODULE_PATH } from './handle-page/handle-page-routing-path
loadChildren: () => import('./handle-page/handle-page.module').then((m) => m.HandlePageModule),
canActivate: [SiteAdministratorGuard],
},
{
path: STATIC_PAGE_PATH,
loadChildren: () => import('./static-page/static-page.module').then((m) => m.StaticPageModule),
},
{ path: '**', pathMatch: 'full', component: ThemedPageNotFoundComponent }
]
}
@@ -271,7 +275,7 @@ import { HANDLE_TABLE_MODULE_PATH } from './handle-page/handle-page-routing-path
initialNavigation: 'enabledBlocking',
preloadingStrategy: NoPreloading,
onSameUrlNavigation: 'reload',
})
}),
],
exports: [RouterModule],
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<div class="container">
<div class="card">
<h5 class="card-header">{{ 'clarin.license.all-page.title' | translate }}</h5>
<ds-loading *ngIf="isLoading" class="text-center"></ds-loading>
<div class="card-body" *ngFor="let clarinLicense of (licensesRD$ | async)">
<h6 class="card-header border-bottom-0 license-card-border"><a [href]="clarinLicense.definition">{{ clarinLicense.name }}</a></h6>
<div class="card-body rounded-bottom license-card-border">
<div>
<div><b>{{'clarin.license.all-page.source' | translate}}</b></div>
<div><a [href]="clarinLicense.definition">{{ clarinLicense.definition }}</a></div>
</div>
<div>
<div><b>{{'clarin.license.all-page.labels' | translate}}</b></div>
<span [ngClass]="'px-1 d-inline label label-license' + ' label-' + clarinLicense.clarinLicenseLabel.label + ' rounded text-white'">
{{clarinLicense.clarinLicenseLabel.title}}
</span>
<span *ngFor="let clarinLicenseLabel of clarinLicense.extendedClarinLicenseLabels"
class="px-1 label label-default rounded text-white ml-1">
{{clarinLicenseLabel.title}}
</span>
</div>
<div>
<div><b>{{'clarin.license.all-page.extra-information' | translate}}</b></div>
<span *ngIf="clarinLicense.requiredInfo == null">{{'clarin.license.all-page.extra-information.default' | translate}}
</span>
<span *ngFor="let requiredInformation of clarinLicense.requiredInfo"
class="px-1 label label-default rounded text-white mr-1">
{{requiredInformation?.value}}
</span>
</div>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.label-PUB {
background-color: #5cb811 !important;
color: white !important;
}

.label-RES {
background-color: #c62d1f !important;
color: white !important;
}

.label-ACA, .label-PDT {
background-color: #ffab23 !important;
color: white !important;
}

.label-default {
background-color: #999 !important;
}

.license-card-border {
border: 1px solid #e3e3e3;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ClarinAllLicensesPageComponent } from './clarin-all-licenses-page.component';
import { createdLicenseRD$, mockLicenseRD$ } from '../../shared/testing/clarin-license-mock';
import { of as observableOf } from 'rxjs';
import { ClarinLicenseDataService } from '../../core/data/clarin/clarin-license-data.service';
import { TranslateModule } from '@ngx-translate/core';

describe('ClarinAllLicensesPageComponent', () => {
let component: ClarinAllLicensesPageComponent;
let fixture: ComponentFixture<ClarinAllLicensesPageComponent>;
let clarinLicenseDataService: ClarinLicenseDataService;

beforeEach(async () => {
clarinLicenseDataService = jasmine.createSpyObj('clarinLicenseService', {
findAll: mockLicenseRD$,
create: createdLicenseRD$,
put: createdLicenseRD$,
searchBy: mockLicenseRD$,
getLinkPath: observableOf('')
});

await TestBed.configureTestingModule({
declarations: [ ClarinAllLicensesPageComponent ],
imports: [
TranslateModule.forRoot(),
],
providers: [
{ provide: ClarinLicenseDataService, useValue: clarinLicenseDataService },
]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(ClarinAllLicensesPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Component, OnInit } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { ClarinLicense } from '../../core/shared/clarin/clarin-license.model';
import { ClarinLicenseDataService } from '../../core/data/clarin/clarin-license-data.service';
import { getFirstSucceededRemoteListPayload } from '../../core/shared/operators';
import { FindListOptions } from '../../core/data/find-list-options.model';

@Component({
selector: 'ds-clarin-all-licenses-page',
templateUrl: './clarin-all-licenses-page.component.html',
styleUrls: ['./clarin-all-licenses-page.component.scss']
})
export class ClarinAllLicensesPageComponent implements OnInit {

/**
* The list of ClarinLicense object as BehaviorSubject object
*/
licensesRD$: BehaviorSubject<ClarinLicense[]> = new BehaviorSubject<ClarinLicense[]>(null);

/**
* If the request isn't processed show to loading bar.
*/
isLoading = false;

constructor(private clarinLicenseService: ClarinLicenseDataService) { }

ngOnInit(): void {
this.loadAllLicenses();
}

loadAllLicenses() {
this.isLoading = true;

const options = new FindListOptions();
options.currentPage = 0;
// Load all licenses
options.elementsPerPage = 1000;
return this.clarinLicenseService.findAll(options, false)
.pipe(getFirstSucceededRemoteListPayload())
.subscribe(res => {
this.licensesRD$.next(this.filterLicensesByLicenseLabel(res));
this.isLoading = false;
});
}

/**
* Show PUB licenses at first, then ACA and RES
* @private
*/
private filterLicensesByLicenseLabel(clarinLicensesResponse: ClarinLicense[]) {
// Show PUB licenses as first.
const pubLicenseArray = [];
// Then show ACA and RES licenses.
const acaResLicenseArray = [];

clarinLicensesResponse?.forEach(clarinLicense => {
if (clarinLicense?.clarinLicenseLabel?.label === 'PUB') {
pubLicenseArray.push(clarinLicense);
} else {
acaResLicenseArray.push(clarinLicense);
}
});

// Sort acaResLicenseArray by the license label (ACA, RES)
acaResLicenseArray.sort((a, b) => a.clarinLicenseLabel?.label?.localeCompare(b.clarinLicenseLabel?.label));

// Concat two array into one.
return pubLicenseArray.concat(acaResLicenseArray);
}

}
32 changes: 25 additions & 7 deletions src/app/clarin-licenses/clarin-license-routing.module.ts
Original file line number Diff line number Diff line change
@@ -2,19 +2,37 @@ import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
import { ClarinLicensePageComponent } from './clarin-license-page/clarin-license-page.component';
import {
SiteAdministratorGuard
} from '../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
import { ClarinAllLicensesPageComponent } from './clarin-all-licenses-page/clarin-all-licenses-page.component';
import { LICENSES_MANAGE_TABLE_PATH } from '../app-routing-paths';

@NgModule({
imports: [
RouterModule.forChild([
{
path: '',
resolve: { breadcrumb: I18nBreadcrumbResolver },
data: {
breadcrumbKey: 'licenses',
},
component: ClarinLicensePageComponent,
pathMatch: 'full'
}
children: [
{
path: '',
resolve: { breadcrumb: I18nBreadcrumbResolver },
component: ClarinAllLicensesPageComponent,
data: {
breadcrumbKey: 'licenses',
}
},
{
path: LICENSES_MANAGE_TABLE_PATH,
component: ClarinLicensePageComponent,
resolve: { breadcrumb: I18nBreadcrumbResolver },
data: {
breadcrumbKey: 'licenses.manage-table',
},
canActivate: [SiteAdministratorGuard],
},
],
},
])
]
})
2 changes: 2 additions & 0 deletions src/app/clarin-licenses/clarin-license.module.ts
Original file line number Diff line number Diff line change
@@ -9,13 +9,15 @@ import { ClarinLicenseTableComponent } from './clarin-license-table/clarin-licen
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { DefineLicenseFormComponent } from './clarin-license-table/modal/define-license-form/define-license-form.component';
import { DefineLicenseLabelFormComponent } from './clarin-license-table/modal/define-license-label-form/define-license-label-form.component';
import { ClarinAllLicensesPageComponent } from './clarin-all-licenses-page/clarin-all-licenses-page.component';

@NgModule({
declarations: [
ClarinLicensePageComponent,
ClarinLicenseTableComponent,
DefineLicenseFormComponent,
DefineLicenseLabelFormComponent,
ClarinAllLicensesPageComponent,
],
imports: [
CommonModule,
3 changes: 2 additions & 1 deletion src/app/menu.resolver.ts
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@ import {
import {
ExportBatchSelectorComponent
} from './shared/dso-selector/modal-wrappers/export-batch-selector/export-batch-selector.component';
import { getLicensesManageTablePath, getLicensesModulePath } from './app-routing-paths';

/**
* Creates all of the app's menus
@@ -394,7 +395,7 @@ export class MenuResolver implements Resolve<boolean> {
model: {
type: MenuItemType.LINK,
text: 'menu.section.licenses',
link: '/licenses'
link: getLicensesModulePath() + getLicensesManageTablePath()
} as LinkMenuItemModel,
icon: 'scroll',
index: 12
22 changes: 22 additions & 0 deletions src/app/shared/html-content.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { of as observableOf } from 'rxjs';

/**
* Service for loading static `.html` files stored in the `/static-files` folder.
*/
@Injectable()
export class HtmlContentService {
constructor(private http: HttpClient) {}

/**
* Load `.html` file content or return empty string if an error.
* @param url file location
*/
fetchHtmlContent(url: string) {
// catchError -> return empty value.
return this.http.get(url, { responseType: 'text' }).pipe(
catchError(() => observableOf('')));
}
}
4 changes: 3 additions & 1 deletion src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
@@ -274,6 +274,7 @@ import {
import { EpersonGroupListComponent } from './eperson-group-list/eperson-group-list.component';
import { EpersonSearchBoxComponent } from './eperson-group-list/eperson-search-box/eperson-search-box.component';
import { GroupSearchBoxComponent } from './eperson-group-list/group-search-box/group-search-box.component';
import { HtmlContentService } from './html-content.service';

const MODULES = [
CommonModule,
@@ -456,7 +457,8 @@ const ENTRY_COMPONENTS = [
const PROVIDERS = [
TruncatableService,
MockAdminGuard,
AbstractTrackableComponent
AbstractTrackableComponent,
HtmlContentService
];

const DIRECTIVES = [
6 changes: 6 additions & 0 deletions src/app/static-page/static-page-routing-paths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Constants for `/static` route.
*/
export const STATIC_PAGE_PATH = 'static';
export const STATIC_FILES_PROJECT_PATH = 'static-files';
export const STATIC_FILES_DEFAULT_ERROR_PAGE_PATH = STATIC_FILES_PROJECT_PATH + '/' + 'error.html';
19 changes: 19 additions & 0 deletions src/app/static-page/static-page-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { StaticPageComponent } from './static-page.component';

const routes: Routes = [
{
path: '',
children: [
{ path: '', component: StaticPageComponent },
{ path: ':htmlFileName', component: StaticPageComponent },
],
},
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class StaticPageRoutingModule { }
3 changes: 3 additions & 0 deletions src/app/static-page/static-page.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="container" >
<div [innerHTML]="(htmlContent | async)"></div>
</div>
3 changes: 3 additions & 0 deletions src/app/static-page/static-page.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/**
File for styling the `static-page` component.
*/
Loading

0 comments on commit 6f146c2

Please sign in to comment.