Skip to content
Snippets Groups Projects
Commit cdc13d07 authored by Olabarrieta Palacios, Ignacio's avatar Olabarrieta Palacios, Ignacio
Browse files
parents 8bdce6d3 c616a490
No related branches found
No related tags found
No related merge requests found
Showing
with 401 additions and 13 deletions
......@@ -39,4 +39,4 @@ ENV DASHBOARD_BASE_URL=http://localhost:4200 \
TRAFFIC_SIMULATION_BASE_URL=http://localhost:8082/traffic-simulation \
TRAFFIC_SIMULATION_STORAGE_URL=http://localhost:8081 \
TRAFFIC_SIMULATION_DSS_URL=http://localhost:8083 \
TRAFFIC_SIMULATION_STOMP_URL=ws://localhost:8082/gs-guide-websocket
TRAFFIC_SIMULATION_STOMP_URL=ws://localhost:/gs-guide-websocket
......@@ -9,7 +9,7 @@ import { Component } from '@angular/core';
<ngx-header></ngx-header>
</nb-layout-header>
<nb-sidebar class="menu-sidebar" tag="menu-sidebar" responsive>
<nb-sidebar class="menu-sidebar" tag="menu-sidebar" responsive style="z-index:999">
<ng-content select="nb-menu"></ng-content>
</nb-sidebar>
......
......@@ -30,6 +30,7 @@
import { AuthGuard } from './auth/services/auth.guard';
import { AuthLogoutComponent } from './auth/logout/auth-logout.component';
import { MarkdownModule } from 'ngx-markdown';
import { UiFeaturesModule } from './pages/ui-features/ui-features.module';
import { ChartModule } from 'angular2-chartjs';
import 'chartjs-plugin-zoom';
......@@ -53,6 +54,7 @@ import { DatastorageService } from './pages/dashboard-management/services/datast
BrowserAnimationsModule,
HttpClientModule,
AppRoutingModule,
UiFeaturesModule,
NbSidebarModule.forRoot(),
NbMenuModule.forRoot(),
NbDatepickerModule.forRoot(),
......
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { ConfigService } from '@ngx-config/core';
import { IDMUser } from '../oauth/model/idmuser';
......@@ -12,9 +12,11 @@ import { map } from 'rxjs/operators';
export class KeyrockUserInformationService {
apiURL: string;
client_id: string;
realm: string;
constructor(configService: ConfigService, private http: HttpClient) {
this.apiURL = configService.getSettings("idmBaseURL");
this.client_id = configService.getSettings("client_id");
this.realm = configService.getSettings("idmRealmName");
}
getRole(): Observable<string[]> {
......@@ -32,6 +34,13 @@ export class KeyrockUserInformationService {
getUser(): Observable<IDMUser> {
return this.http.get<IDMUser>(`${this.apiURL}/user`);
}
getUsers(): any {
let httpHeaders = new HttpHeaders( {"Access-Control-Allow-Origin": "*","Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization", "Access-Control-Allow-Methods": "GET, POST, PUT, OPTIONS, DELETE"});
return this.http.get(`${this.apiURL}/${this.realm}/users`, {
headers: httpHeaders,
} );
}
getLogoutUrl(): string {
return `${this.apiURL}/auth/external_logout?_method=DELETE&client_id=${this.client_id}`;
......
......@@ -8,25 +8,30 @@ import {
import { Observable } from 'rxjs';
import { NbAuthOAuth2JWTToken, NbAuthOAuth2Token, NbAuthService } from '@nebular/auth';
import { ConfigService } from '@ngx-config/core';
import { switchMap, tap } from 'rxjs/operators';
import { finalize, switchMap, tap } from 'rxjs/operators';
import { LoaderService } from '../../services/loader.service';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
token;
constructor(public auth: NbAuthService, public config:ConfigService) {}
constructor(public auth: NbAuthService, public config:ConfigService, public loaderService:LoaderService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.loaderService.show();
if (req.url.indexOf('/assets/') > -1) {
return next.handle(req);
return next.handle(req).pipe(
finalize(() => this.loaderService.hide()));
}
if (req.url.indexOf('/oauth2/token') > -1 || req.url.indexOf('/openid-connect/token') > -1 || req.url.indexOf('/api/menu-blocks') > -1|| req.url.indexOf('/public/dashboards') > -1) {
return next.handle(req);
return next.handle(req).pipe(
finalize(() => this.loaderService.hide()));
}
if (req.url.indexOf(this.config.getSettings('idra_base_url')+'/Idra') > -1) {
return next.handle(req);
return next.handle(req).pipe(
finalize(() => this.loaderService.hide()));
}
......@@ -45,12 +50,14 @@ export class TokenInterceptor implements HttpInterceptor {
newHeaders = newHeaders.append('Authorization', 'Bearer ' + this.token.getPayload().access_token);
}
const authReq = req.clone({ headers: newHeaders });
return next.handle(authReq);
return next.handle(authReq).pipe(
finalize(() => this.loaderService.hide()));
})
)
} else {
const authReq = req.clone({ headers: newHeaders });
return next.handle(authReq);
return next.handle(authReq).pipe(
finalize(() => this.loaderService.hide()));
}
}
......
......@@ -3,6 +3,7 @@ import { RouterModule, Routes } from '@angular/router';
import { DataCatalogueComponent } from './data-catalogue.component';
import { DatasetComponent } from './dataset/dataset.component';
import { SearchComponent } from './search/search.component';
import {DatasetFilteredComponent} from './dataset-filtered/dataset-filtered.component';
const routes: Routes = [
{
......@@ -14,10 +15,15 @@ const routes: Routes = [
path: '',
component: SearchComponent
},
{
path:'filtered',
component: DatasetFilteredComponent
},
{
path:':id',
component: DatasetComponent
}]
},
]
}];
@NgModule({
......
......@@ -12,8 +12,9 @@ import { DistributionComponent } from './distribution/distribution.component';
import { MarkdownModule } from 'ngx-markdown';
import { DataletIframeComponent } from './datalet-iframe/datalet-iframe.component';
import { ShowDataletsComponent } from './show-datalets/show-datalets.component';
import { DatasetFilteredComponent } from './dataset-filtered/dataset-filtered.component';
@NgModule({
declarations: [DataCatalogueComponent, SearchComponent, DatasetComponent, DistributionComponent, DataletIframeComponent, ShowDataletsComponent],
declarations: [DataCatalogueComponent, SearchComponent, DatasetComponent, DistributionComponent, DataletIframeComponent, ShowDataletsComponent, DatasetFilteredComponent],
imports: [
ThemeModule,
NbFormFieldModule,
......
<div [nbSpinner]="loading" nbSpinnerSize="giant" nbSpinnerStatus="primary">
<div class="row" *ngIf="searchResponse.count>0">
<div class="col-12">
<!-- results -->
<nb-card *ngFor="let dataset of searchResponse.results | slice:0:10; let i=index" class="minicard">
<nb-card-header>
<a routerLink="/pages/datasets/{{dataset.id}}">{{dataset.title}}</a>
</nb-card-header>
<nb-card-body class="content-truncated">
<span class="truncated">{{dataset.description}}</span>
</nb-card-body>
<nb-card-footer>
<nb-tag-list size="small">
<nb-tag *ngFor="let tmp of dataset.distributionFormats" text="{{tmp.format}} ({{tmp.count}})" size="tiny" [style.background]="getColor(tmp.format)">
</nb-tag>
</nb-tag-list>
</nb-card-footer>
</nb-card>
</div>
</div>
</div>
.no-border{
border: none;
:first-child{
border: none;
}
}
.truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.content-truncated {
width:100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.minicard{
height:unset;
}
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DatasetFilteredComponent } from './dataset-filtered.component';
describe('DatasetFilteredComponent', () => {
let component: DatasetFilteredComponent;
let fixture: ComponentFixture<DatasetFilteredComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ DatasetFilteredComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DatasetFilteredComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { NbTagComponent, NbTagInputAddEvent } from '@nebular/theme';
import { DCATDataset,FormatCount } from '../model/dcatdataset';
import { ODMSCatalogueInfo } from '../model/odmscatalogue-info';
import { SearchFacet } from '../model/search-facet';
import { SearchFilter } from '../model/search-filter';
import { SearchRequest } from '../model/search-request';
import { SearchResult } from '../model/search-result';
import { DataCataglogueAPIService } from '../services/data-cataglogue-api.service';
import { NbLayoutScrollService } from '@nebular/theme';
import {KeyrockUserInformationService} from '../../../auth/services/keyrock-user-information.service';
import { OidcUserInformationService } from '../../../auth/services/oidc-user-information.service';
@Component({
selector: 'ngx-dataset-filtered',
templateUrl: './dataset-filtered.component.html',
styleUrls: ['./dataset-filtered.component.scss']
})
export class DatasetFilteredComponent implements OnInit {
separatorKeys:number[] = [13, 188];
searchResponse:SearchResult=new SearchResult();
searchRequest:SearchRequest=new SearchRequest();
cataloguesInfos: Array<ODMSCatalogueInfo>=[];
user: any;
tags: string[] = [];
constructor(private restApi:DataCataglogueAPIService, private nbScroll: NbLayoutScrollService,private userService: OidcUserInformationService, private keyrockUserInformationService: KeyrockUserInformationService ) { }
loading=false;
facetLimits={};
page: number = 1;
@Input()
totalDatasets:number=0;
filters: Array<string> = [];
filtersTags: Array<string>= [];
ngOnInit(): void {
this.userService.onUserChange()
.subscribe((user: any) => {
this.user = user;
if (this.user.hasOwnProperty('topics')) {
this.tags = this.user.topics.topics;
}
if (this.tags.length > 0) {
this.tags.forEach(element => {
this.searchDatasetOnTagsValue(element);
});
}
});
}
searchDatasetOnTagsValue(tag) {
this.searchRequest.nodes.push(1);
let index = this.searchRequest.filters.findIndex(x=> x.field==="ALL");
if(index<0){
this.searchRequest.filters.push(new SearchFilter("ALL",tag));
}else{
let filter=this.searchRequest.filters[index];
filter.value=tag;
}
this.searchOnFilter();
/* tags.forEach(element => {
console.log(element);
this.searchRequest.filters.push(new SearchFilter('ALL',element));
this.searchOnFilter();
});*/
}
searchOnFilter(){
this.restApi.searchDatasets(this.searchRequest).subscribe(
res=>{
// this.searchResponse=res
if (res.count > 0){
console.log(res);
console.log(this.searchResponse);
this.totalDatasets = this.totalDatasets + res.count;
let oldResult = this.searchResponse.results;
if (oldResult === undefined){
this.searchResponse=res;
this.searchResponse.results.map((x:DCATDataset)=>{ this.processDataset(x) })
} else {
console.log(oldResult);
let newResult = oldResult.concat(res.results);
console.log(newResult);
this.searchResponse.count= this.searchResponse.count + res.count;
this.searchResponse.results= newResult;
console.log(this.searchResponse);
this.searchResponse.results.map((x:DCATDataset)=>{ this.processDataset(x) })
}
this.loading=false;
}
},
err=>{
console.log(err);
this.loading=false;
});
}
processDataset(dataset:DCATDataset):DCATDataset{
let tmp=[];
dataset.distributionFormats=[];
for(let d of dataset.distributions){
if(tmp.indexOf(d.format)<0){
let fC=new FormatCount();
fC.format=d.format;
fC.count=1;
dataset.distributionFormats.push(fC);
tmp.push(d.format);
}else{
dataset.distributionFormats[tmp.indexOf(d.format)].count++;
}
}
dataset.description = dataset.description.replace(/\*/g,'').replace(/\\n/g,'')
.replace(/\(http.*\)/g,'').replace(/##\s*/g,'')
.replace(/<.*>(.*)<\/.*>/g,'$1')
.replace(/>/g,'').replace(/\[|\]/g,'')
return dataset;
}
getColor(format:string):string{
switch(format.toLowerCase()){
case 'csv':
return '#dfb100';
case 'html':
return '#55a1ce';
case 'json':
case 'xml':
return '#ef7100';
case 'text':
case 'txt':
return '#74cbec';
case 'xls':
case 'xlsx':
return '#2db55d';
case 'zip':
return '#686868';
case 'api':
return 'ec96be';
case 'pdf':
return '#e0051e';
case 'rdf':
case 'nquad':
case 'turtle':
case 'ntriples':
return '#0b4498';
case 'fiware':
case 'ngsi':
case 'ngsi-ld':
case 'fiware-ngsi':
case 'fiware-ngsi-ld':
return '#65c3d1';
default:
return 'default';
}
}
}
......@@ -174,6 +174,14 @@ export const MENU_ITEMS: NbMenuItem[] = [
name: "dashboard-management",
},
},
{
title: "Most relevant dataset",
icon: "search-outline",
link: "/pages/datasets/filtered",
data: {
name: "catalogues",
},
},
{
title: "Data Catalogue",
icon: "search-outline",
......
......@@ -12,6 +12,7 @@ import { MENU_ITEMS } from './pages-menu';
selector: 'ngx-pages',
styleUrls: ['pages.component.scss'],
template: `
<ngx-loader></ngx-loader>
<ngx-one-column-layout>
<nb-menu [items]="menu"></nb-menu>
<router-outlet></router-outlet>
......
......@@ -9,6 +9,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { UtilitiesComponent } from './utilities/utilities.component';
import { MapLayersComponent } from './map-layers/map-layers.component';
import { GuideComponent } from './guide/guide.component';
import { UiFeaturesModule } from './ui-features/ui-features.module';
@NgModule({
......@@ -20,6 +21,7 @@ import { GuideComponent } from './guide/guide.component';
MiscellaneousModule,
TranslateModule,
NbStepperModule,
UiFeaturesModule
],
declarations: [
PagesComponent,
......
<!--<div class="overlay" *ngIf="isLoadingValue" [nbSpinner]="true" nbSpinnerSize="giant" nbSpinnerStatus="primary">
</div>-->
<style>@-webkit-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-moz-keyframes spin{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.spinner{position:fixed;top:0;left:0;width:100%;height:100%;z-index:3;background: rgba(254, 253, 253, 0.8);overflow:hidden} .spinner div:first-child{display:block;position:relative;left:50%;top:50%;width:150px;height:150px;margin:-75px 0 0 -75px;border-radius:50%;box-shadow:0 3px 3px 0 rgba(19,153,114,1);transform:translate3d(0,0,0);animation:spin 2s linear infinite} .spinner div:first-child:after,.spinner div:first-child:before{content:'';position:absolute;border-radius:50%} .spinner div:first-child:before{top:5px;left:5px;right:5px;bottom:5px;box-shadow:0 3px 3px 0 rgb(234,206,0);-webkit-animation:spin 3s linear infinite;animation:spin 3s linear infinite} .spinner div:first-child:after{top:15px;left:15px;right:15px;bottom:15px;box-shadow:0 3px 3px 0 rgba(244,230,127,1);animation:spin 1.5s linear infinite}</style>
<div id="nb-global-spinner" class="spinner" *ngIf="isLoadingValue">
<div class="blob blob-0"></div>
<div class="blob blob-1"></div>
<div class="blob blob-2"></div>
<div class="blob blob-3"></div>
<div class="blob blob-4"></div>
<div class="blob blob-5"></div>
</div>
.overlay {
position: fixed;
// display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba(202, 202, 202, 0.8);
//background-color: red;
z-index: 3;
// z-index: 99999;
}
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LoaderComponent } from './loader.component';
describe('LoaderComponent', () => {
let component: LoaderComponent;
let fixture: ComponentFixture<LoaderComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ LoaderComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(LoaderComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit,ChangeDetectionStrategy, SimpleChanges, ChangeDetectorRef } from '@angular/core';
import { LoaderService } from '../../../services/loader.service';
import { BehaviorSubject, Subject } from 'rxjs';
import { threadId } from 'worker_threads';
@Component({
selector: 'ngx-loader',
templateUrl: './loader.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./loader.component.scss']
})
export class LoaderComponent implements OnInit {
isLoading;
noLoader;
constructor(private loaderService: LoaderService, private changeDetectorRef: ChangeDetectorRef) {
changeDetectorRef.detach();
setInterval(() => { this.changeDetectorRef.detectChanges(); }, 500);
}
get isLoadingValue(){
return this.isLoading;
}
ngOnInit(): void {
this.loaderService.loader.subscribe(color => {console.log(color);
this.isLoading = color;
//
});
this.changeDetectorRef.detectChanges();
//this.isLoading = this.loaderService.isLoading$.getValue();
}
}
import { NgModule } from '@angular/core';
import { NbAlertModule, NbCardModule, NbIconModule, NbPopoverModule, NbSearchModule } from '@nebular/theme';
import { NbAlertModule, NbCardModule, NbIconModule, NbPopoverModule, NbSearchModule, NbSpinnerModule } from '@nebular/theme';
import { ThemeModule } from '../../@theme/theme.module';
import { UiFeaturesRoutingModule } from './ui-features-routing.module';
......@@ -7,12 +7,16 @@ import { UiFeaturesComponent } from './ui-features.component';
import { GridComponent } from './grid/grid.component';
import { IconsComponent } from './icons/icons.component';
import { TypographyComponent } from './typography/typography.component';
import { LoaderComponent } from './loader/loader.component';
const components = [
UiFeaturesComponent,
GridComponent,
IconsComponent,
TypographyComponent,
LoaderComponent
];
@NgModule({
......@@ -24,9 +28,13 @@ const components = [
NbAlertModule,
ThemeModule,
UiFeaturesRoutingModule,
NbSpinnerModule
],
declarations: [
...components,
],
exports: [ ...components,
],
})
export class UiFeaturesModule { }
import { TestBed } from '@angular/core/testing';
import { LoaderService } from './loader.service';
describe('LoaderService', () => {
let service: LoaderService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(LoaderService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment