[Admin]: Add criteria on content providers.(Available only for development).

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-admin-portal/trunk@57262 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
k.triantafyllou 2019-10-04 08:47:16 +00:00
parent de6551b6cf
commit 76b825c0a2
10 changed files with 412 additions and 98 deletions

View File

@ -149,6 +149,11 @@ const appRoutes: Routes = [
loadChildren: './pages/community/content-providers/communityContentProviders.module#CommunityContentProvidersModule',
resolve: { envSpecific: EnvironmentSpecificResolver }
},
{
path: 'manage-content-providers/criteria',
loadChildren: './pages/community/content-providers/criteria/criteria.module#CriteriaModule',
resolve: { envSpecific: EnvironmentSpecificResolver }
},
{
path: 'mining',
loadChildren: './pages/mining/mining.module#MiningModule',

View File

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import {RouterModule} from '@angular/router';
import {IsCommunity} from '../../../../openaireLibrary/connect/communityGuard/isCommunity.guard';
import {ConnectAdminLoginGuard} from '../../../../openaireLibrary/connect/communityGuard/connectAdminLoginGuard.guard';
import {CriteriaComponent} from './criteria.component';
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', canActivate: [IsCommunity, ConnectAdminLoginGuard], component: CriteriaComponent}
])
]
})
export class CriteriaRoutingModule { }

View File

@ -0,0 +1,108 @@
<div *ngIf="showLoading" class="uk-animation-fade uk-width-1-1" role="alert">
<span class="loading-gif uk-align-center"></span>
</div>
<div *ngIf="dataProvider" class="uk-padding uk-padding-remove-bottom">
<div class="uk-flex uk-flex-middle" uk-grid>
<div class="uk-flex uk-flex-middle uk-width-4-5">
<a class="uk-icon uk-margin-right" uk-icon="icon: arrow-left; ratio: 2"
routerLink="/manage-content-providers" [queryParams]="{communityId: community}"></a>
<div class="uk-width-expand">
<span>Criteria for</span><br>
<span class="uk-text-large uk-text-bold">{{dataProvider.officialname}}</span>
</div>
</div>
<div class="uk-width-expand uk-text-right">
<button class="uk-button uk-width-1-2@l uk-button-danger"
(click)="save()">Save</button>
</div>
</div>
<div class="uk-alert uk-alert-primary uk-flex uk-flex-middle uk-margin-medium-top">
<span class="uk-icon uk-margin-small-right" uk-icon="info"></span>
<div class="uk-width-expand">
If no criteria are specified, all research results of this content provider will be included in your community.
</div>
</div>
<div class="uk-margin-top uk-margin-bottom">
<span>Add criteria to limit research results.</span><br>
<span>Results which satisfy any of the above criteria will be included in your community.</span>
</div>
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger" role="alert">{{errorMessage}}</div>
<div *ngIf="criteria.length === 0"
class="uk-padding uk-position-relative">
<div class="uk-position-center">
No criteria are specified
</div>
</div>
<div *ngIf="criteria.controls.length > 0" [formGroup]="selcrit">
<div formArrayName="criteria">
<div class="uk-margin-top" *ngFor="let criterion of criteria.controls; let i=index" [formGroupName]="i">
<span class="uk-text-uppercase uk-text-large uk-margin-small-bottom">Criterion {{i + 1}}</span><br>
<div class="uk-padding" style="border: solid 1px;" formArrayName="constraint">
<div class="uk-flex uk-flex-middle uk-grid-small uk-margin-small-bottom" uk-grid>
<div class="uk-width-1-5">
<label class="uk-text-uppercase uk-text-muted">Constraint Field</label>
</div>
<div class="uk-width-1-5">
<label class="uk-text-uppercase uk-text-muted">Operator</label>
</div>
<div class="uk-width-2-5">
<label class="uk-text-uppercase uk-text-muted">Term</label>
</div>
</div>
<div *ngFor="let constraint of getConstraint(i).controls; let j=index"
[formGroupName]="j" class="uk-margin-bottom">
<div class="uk-flex uk-flex-middle uk-grid-small" uk-grid>
<div class="uk-width-1-5">
<select formControlName="field" class="form-control uk-select"
[class.uk-text-muted]="constraint.get('field').value === ''"
[class.uk-form-danger]="constraint.get('field').status === 'INVALID'">
<option [value]="''" disabled selected hidden>Select a field...</option>
<option [value]="'title'">title</option>
<option [value]="'author'">author's name</option>
<option [value]="'author ORCID'">author's ORCID</option>
<option [value]="'contributor'">contributor</option>
<option [value]="'description'">description</option>
</select>
</div>
<div class="uk-width-1-5">
<select formControlName="verb" class="form-control uk-select"
[class.uk-form-danger]="constraint.get('verb').status === 'INVALID'">
<option [value]="'contains'">contains</option>
<option [value]="'equals'">equals</option>
<option [value]="'not_contains'">not contains</option>
<option [value]="'not_equals'">not equals</option>
</select>
</div>
<div class="uk-width-2-5">
<input type="text" class="uk-input" formControlName="value" placeholder="Type term..."
[class.uk-form-danger]="constraint.get('value').status === 'INVALID'">
</div>
<div class="uk-width-1-6">
<span *ngIf="getConstraint(i).length > j + 1">AND</span>
</div>
<div class="uk-width-expand" *ngIf="getConstraint(i).length > 1">
<button class="uk-icon-button uk-button-danger uk-icon uk-margin-small-right"
uk-icon="minus" (click)="removeConstraint(i, j)"></button>
</div>
<div class="uk-width-expand" *ngIf="getConstraint(i).length === 1">
<button class="uk-icon-button uk-button-danger uk-icon uk-margin-small-right"
uk-icon="minus" (click)="removeConstraint(i, j)"
uk-tooltip="title: By removing this constraint, the criterion will be removed too."></button>
</div>
</div>
</div>
<div class="uk-margin-top uk-flex uk-flex-middle uk-flex-right">
<button class="uk-icon-button uk-button-danger uk-icon uk-margin-small-right"
(click)="addConstraint(i)" uk-icon="plus"></button>
<span class="uk-text-uppercase clickable" (click)="addConstraint(i)">Add Constraint</span>
</div>
</div>
</div>
</div>
</div>
<div class="uk-margin-top uk-flex uk-flex-middle">
<button class="uk-icon-button uk-button-danger uk-icon uk-margin-small-right"
(click)="addCriteria()" uk-icon="plus"></button>
<span class="uk-text-uppercase clickable" (click)="addCriteria()">Add Criterion</span>
</div>
</div>

View File

@ -0,0 +1,135 @@
import {Component, OnInit} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {HelperFunctions} from '../../../../openaireLibrary/utils/HelperFunctions.class';
import {SearchCommunityDataprovidersService} from '../../../../openaireLibrary/connect/contentProviders/searchDataproviders.service';
import {EnvProperties} from '../../../../openaireLibrary/utils/properties/env-properties';
import {ContentProvider} from '../../../../openaireLibrary/utils/entities/contentProvider';
import {FormArray, FormBuilder, FormGroup, Validators} from '@angular/forms';
import {ManageCommunityContentProvidersService} from '../../../../services/manageContentProviders.service';
@Component({
selector: 'criteria',
templateUrl: './criteria.component.html'
})
export class CriteriaComponent implements OnInit {
public community: string = '';
public openaireId: string = '';
public dataProvider: ContentProvider = null;
public selcrit: FormGroup;
private properties: EnvProperties;
showLoading = true;
public errorMessage: string;
constructor(private route: ActivatedRoute, private _router: Router,
private searchCommunityDataprovidersService: SearchCommunityDataprovidersService,
private manageCommunityContentProvidersService: ManageCommunityContentProvidersService,
private fb: FormBuilder) {
}
ngOnInit() {
this.route.data.subscribe((data: { envSpecific: EnvProperties }) => {
this.properties = data.envSpecific;
this.route.queryParams.subscribe(params => {
if (params['communityId']) {
this.community = params['communityId'];
}
if (params['openaireId']) {
this.openaireId = params['openaireId'];
}
this.searchCommunityDataprovidersService.searchDataproviders(this.properties, this.community).subscribe(dataProviders => {
dataProviders.forEach(dataProvider => {
if (dataProvider.openaireId == this.openaireId) {
this.dataProvider = dataProvider;
}
});
if (!this.dataProvider) {
this._router.navigate(['manage-content-providers'],
{queryParams: {'communityId': this.community}});
}
this.buildForm();
this.showLoading = false;
});
HelperFunctions.scroll();
});
});
}
public ngOnDestroy() {
}
buildForm() {
this.selcrit = this.fb.group({
criteria: this.fb.array([])
});
if (this.dataProvider.selcrit) {
this.dataProvider.selcrit.criteria.forEach(criteria => {
let constraintArray: FormArray = this.fb.array([]);
criteria.constraint.forEach(constraint => {
constraintArray.push(this.fb.group({
field: this.fb.control(constraint.field, Validators.required),
verb: this.fb.control(constraint.verb, Validators.required),
value: this.fb.control(constraint.value, Validators.required)
}));
});
this.criteria.push(this.fb.group({
constraint: constraintArray
}));
});
}
}
public get criteria(): FormArray {
return this.selcrit.get('criteria') as FormArray;
}
public getConstraint(i: number): FormArray {
return this.criteria.at(i).get('constraint') as FormArray;
}
public addCriteria() {
let constraintArray: FormArray = this.fb.array([
this.fb.group({
field: this.fb.control('', Validators.required),
verb: this.fb.control('contains', Validators.required),
value: this.fb.control('', Validators.required)
})
]);
this.criteria.push(this.fb.group({
constraint: constraintArray
}));
}
public addConstraint(i: number) {
let constraintArray: FormArray = this.criteria.at(i).get('constraint') as FormArray;
constraintArray.push(this.fb.group({
field: this.fb.control('', Validators.required),
verb: this.fb.control('contains', Validators.required),
value: this.fb.control('', Validators.required)
}));
}
public removeConstraint(i: number, j: number) {
let constraintArray: FormArray = this.criteria.at(i).get('constraint') as FormArray;
constraintArray.removeAt(j);
if (constraintArray.length === 0) {
this.criteria.removeAt(i);
}
}
save() {
this.errorMessage = null;
if (this.selcrit.status === 'VALID') {
this.dataProvider.selcrit = this.selcrit.value;
console.log(this.dataProvider);
this.manageCommunityContentProvidersService.
saveContentProvider(this.properties, this.dataProvider).subscribe( () => {
this._router.navigate(['manage-content-providers'], {
queryParams: {communityId: this.dataProvider.communityId}
});
});
} else {
this.errorMessage = 'Please fill all fields of each constraint or remove all constraints with empty fields.';
}
}
}

View File

@ -0,0 +1,32 @@
import {NgModule} from '@angular/core';
import {EnvironmentSpecificResolver} from '../../../../openaireLibrary/utils/properties/environmentSpecificResolver';
import {EnvironmentSpecificService} from '../../../../openaireLibrary/utils/properties/environment-specific.service';
import {CommonModule} from '@angular/common';
import {CriteriaComponent} from './criteria.component';
import {CriteriaRoutingModule} from './criteria-routing.module';
import {SearchCommunityDataprovidersService} from '../../../../openaireLibrary/connect/contentProviders/searchDataproviders.service';
import {RouterModule} from '@angular/router';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {ManageCommunityContentProvidersService} from '../../../../services/manageContentProviders.service';
@NgModule({
imports: [
CommonModule,
CriteriaRoutingModule,
RouterModule,
FormsModule,
ReactiveFormsModule,
],
declarations: [
CriteriaComponent
],
providers: [
SearchCommunityDataprovidersService,
ManageCommunityContentProvidersService,
EnvironmentSpecificResolver, EnvironmentSpecificService
],
exports: [CriteriaComponent]
})
export class CriteriaModule { }

View File

@ -1,80 +1,102 @@
<div class="uk-child-width-expand@s uk-text-center uk-margin-bottom" uk-grid>
<div class="uk-child-width-expand@s uk-text-center uk-margin-bottom" uk-grid>
<div>
<form class="uk-text-center uk-animation uk-card uk-card-default uk-padding">
<div>
<input type="text" class="uk-input uk-width-1-2" placeholder="Search community content providers..." aria-describedby="sizing-addon2" [(ngModel)]="communitySearchUtils.keyword" name="keyword" >
<input type="text" class="uk-input uk-width-1-2" placeholder="Search community content providers..."
aria-describedby="sizing-addon2" [(ngModel)]="communitySearchUtils.keyword" name="keyword">
<button (click)="goTo(1)" type="submit" class=" uk-button">
<span class="uk-icon">
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="search" ratio="1"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9" cy="9" r="7"></circle><path fill="none" stroke="#000" stroke-width="1.1" d="M14,14 L18,18 L14,14 Z"></path></svg>
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="search" ratio="1"><circle
fill="none" stroke="#000" stroke-width="1.1" cx="9" cy="9" r="7"></circle><path fill="none" stroke="#000"
stroke-width="1.1"
d="M14,14 L18,18 L14,14 Z"></path></svg>
</span>Search
</button>
</div>
</form>
</div>
</div>
<div class="uk-alert uk-alert-primary uk-margin-top-large">
</div>
<div class="uk-alert uk-alert-primary uk-margin-top-large">
<div><span class="uk-margin-small-right uk-icon" uk-icon="warning"></span>
All the research results collected from the content providers specified here will be automatically linked to your community dashboard.
All the research results collected from the content providers specified here will be automatically linked to your
community dashboard.
</div>
</div>
<errorMessages [status]="[communitySearchUtils.status]" [type]="'community Content Providers'"></errorMessages>
</div>
<errorMessages [status]="[communitySearchUtils.status]" [type]="'community Content Providers'"></errorMessages>
<div *ngIf="communitySearchUtils.totalResults > 0" class="uk-align-center uk-margin-remove-bottom">
<div *ngIf="communitySearchUtils.totalResults > 0" class="uk-align-center uk-margin-remove-bottom">
<div class="searchPaging uk-panel uk-margin-top uk-grid uk-margin-bottom">
<span class="uk-h6 uk-width-1-1@s uk-width-1-2@m">
{{communitySearchUtils.totalResults | number}} content providers, page {{communitySearchUtils.page | number}} of {{(totalPages()) | number}}
{{communitySearchUtils.totalResults | number}} content providers, page {{communitySearchUtils.page | number}}
of {{(totalPages()) | number}}
</span>
<span class="float-children-right-at-medium margin-small-top-at-small uk-width-1-1@s uk-width-1-2@m">
<paging-no-load [currentPage]="communitySearchUtils.page" [totalResults]="communitySearchUtils.totalResults" [size]="10" (pageChange)="goTo($event.value, false)"></paging-no-load>
<paging-no-load [currentPage]="communitySearchUtils.page" [totalResults]="communitySearchUtils.totalResults"
[size]="10" (pageChange)="goTo($event.value, false)"></paging-no-load>
</span>
</div>
</div>
</div>
<!-- uk-first-column uk-width-expand -->
<div class="custom-dataTable-content">
<div class="custom-dataTable-content">
<div class="uk-overflow-container">
<table datatable class="uk-table uk-table-striped divider-table" [dtOptions]="dtOptions" id="dpTable" [dtTrigger]="dtTrigger" dtInstance="dtInstanceCallback">
<table datatable class="uk-table uk-table-striped divider-table" [dtOptions]="dtOptions" id="dpTable"
[dtTrigger]="dtTrigger" dtInstance="dtInstanceCallback">
<thead>
<tr>
<th class="uk-text-center">Name</th>
<th class="uk-text-center">Official Name</th>
<th class="uk-text-center" *ngIf="properties.environment === 'development'">Criteria</th>
<th class="uk-text-center">Action</th>
</tr>
</thead>
<tbody>
<tr class="uk-table-middle" *ngFor="let result of communityContentProviders">
<td class="uk-text-center uk-width-1-3">
<td class="uk-text-center uk-width-1-4">
<a class="custom-external" target="_blank"
[href]="communityUrl+'/search/dataprovider?datasourceId=' +result.openaireId">
<span *ngIf="result.name">{{result.name}}</span>
<span *ngIf="!result.name">[no name available]</span>
</a>
</td>
<td class="uk-text-center uk-width-1-3">
<td class="uk-text-center uk-width-1-4">
<span *ngIf="result.officialname">{{result.officialname}}</span>
<span *ngIf="!result.officialname">-</span>
</td>
<td class="uk-text-center uk-width-1-3">
<!-- red_background_color red_color-->
<a (click)="removeContentProvider(result)" class="uk-icon-button remove uk-button-danger" uk-icon="icon: close; ratio: 1" title="Remove"></a>
<td class="uk-text-center uk-width-1-4" *ngIf="properties.environment === 'development'">
<input title="Edit" src="assets/imgs/icn_edit.png"
(click)="goToCriteria(result.openaireId)"
class="edit uk-margin-small-right" type="image">
<span *ngIf="result.selcrit && result.selcrit.criteria.length > 0"
(click)="goToCriteria(result.openaireId)"
class="clickable">{{result.selcrit.criteria.length}} criteria</span>
<span *ngIf="!result.selcrit || result.selcrit.criteria.length === 0"
(click)="goToCriteria(result.openaireId)"
class="clickable">no criteria</span>
</td>
<td class="uk-text-center uk-width-1-4">
<!-- red_background_color red_color-->
<a (click)="removeContentProvider(result)" class="uk-icon-button remove uk-button-danger"
uk-icon="icon: close; ratio: 1" title="Remove"></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div *ngIf="communitySearchUtils.totalResults > 0" class="uk-align-center uk-margin-remove-bottom">
<div *ngIf="communitySearchUtils.totalResults > 0" class="uk-align-center uk-margin-remove-bottom">
<div class="searchPaging uk-panel uk-margin-top uk-grid uk-margin-bottom">
<span class="uk-h6 uk-width-1-1@s uk-width-1-2@m">
{{communitySearchUtils.totalResults | number}} content providers, page {{communitySearchUtils.page | number}} of {{(totalPages()) | number}}
{{communitySearchUtils.totalResults | number}} content providers, page {{communitySearchUtils.page | number}}
of {{(totalPages()) | number}}
</span>
<span class="float-children-right-at-medium margin-small-top-at-small uk-width-1-1@s uk-width-1-2@m">
<paging-no-load [currentPage]="communitySearchUtils.page" [totalResults]="communitySearchUtils.totalResults" [size]="10" (pageChange)="goTo($event.value, false)"></paging-no-load>
<paging-no-load [currentPage]="communitySearchUtils.page" [totalResults]="communitySearchUtils.totalResults"
[size]="10" (pageChange)="goTo($event.value, false)"></paging-no-load>
</span>
</div>
</div>
</div>
<modal-alert #AlertModalDeleteCommunity (alertOutput)="confirmedDeleteContentProvider($event)"></modal-alert>
<modal-alert #AlertModalDeleteCommunity (alertOutput)="confirmedDeleteContentProvider($event)"></modal-alert>

View File

@ -306,4 +306,14 @@ export class RemoveContentProvidersComponent implements OnInit {
);
}
}
goToCriteria(openaireId: string) {
this._router.navigate(['criteria'], {
queryParams: {
communityId: this.community,
openaireId: openaireId
},
relativeTo: this.route
})
}
}

View File

@ -158,7 +158,6 @@ export class CuratorComponent implements OnInit {
for (let page of community.pages) {
if (page['route'] === '/curators') {
this.curatorsEnabled = page['isEnabled'];
console.log(this.curatorsEnabled);
return;
}
}

View File

@ -1,45 +1,34 @@
import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import{EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
import {ContentProvider} from '../openaireLibrary/utils/entities/contentProvider';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class ManageCommunityContentProvidersService {
constructor(private http: HttpClient ) {}
removeContentProvider (properties:EnvProperties, communityId: string, id: string):any {
//let headers = new Headers({'Content-Type': 'application/json', 'accept': 'application/json'});
//let options = new RequestOptions({headers: headers, body: id});
constructor(private http: HttpClient) {
}
removeContentProvider(properties: EnvProperties, communityId: string, id: string): any {
let headers = new HttpHeaders({'Content-Type': 'application/json', 'accept': 'application/json'});
let url = properties.communityAPI+communityId+"/contentproviders";
//return this.http.delete(url, options)
return this.http.request('delete', url, { body: id, headers: headers})
let url = properties.communityAPI + communityId + '/contentproviders';
return this.http.request('delete', url, {body: id, headers: headers});
}
addContentProvider(properties:EnvProperties, communityId: string, contentProvider: any) {
//let headers = new Headers({'Content-Type': 'application/json'});
//let options = new RequestOptions({headers: headers});
let headers = new HttpHeaders({'Content-Type': 'application/json'});
let url = properties.communityAPI+communityId+"/contentproviders";
addContentProvider(properties: EnvProperties, communityId: string, contentProvider: any): Observable<ContentProvider> {
let url = properties.communityAPI + communityId + '/contentproviders';
let communityContentProvider = this.convertSearchContentProviderToCommunityContentProvider(contentProvider, communityId);
return this.http.post<any>(url, JSON.stringify(communityContentProvider), {headers: headers});
//return this.http.post(url, JSON.stringify(communityContentProvider), options)
//.map(res => <any> res.json())
return this.http.post<ContentProvider>(url, communityContentProvider);
}
convertSearchContentProviderToCommunityContentProvider(contentProvider: any, community: string) : any {
let communityContentProvider = {
"communityId": community,
"officialname": "",
"name": "",
"openaireId": ""
saveContentProvider(properties: EnvProperties, contentProvider: ContentProvider): Observable<ContentProvider> {
let url = properties.communityAPI + contentProvider.communityId + '/contentproviders';
return this.http.post<ContentProvider>(url, contentProvider);
}
convertSearchContentProviderToCommunityContentProvider(contentProvider: any, community: string): ContentProvider {
let communityContentProvider: ContentProvider = new ContentProvider();
communityContentProvider.communityId = community;
communityContentProvider.officialname = contentProvider.title.name;
communityContentProvider.name = contentProvider.englishname;
communityContentProvider.openaireId = contentProvider.id;

View File

@ -1,5 +1,5 @@
{
"environment":"production",
"environment":"development",
"enablePiwikTrack" : false,
"useCache" : false,
"metricsAPIURL" : "https://beta.services.openaire.eu/usagestats/",
@ -32,9 +32,9 @@
"vocabulariesAPI" :"https://beta.services.openaire.eu/provision/mvc/vocabularies/",
"piwikBaseUrl" :" https://analytics.openaire.eu/piwik.php?idsite=6",
"loginUrl" :"http://rudie.di.uoa.gr:8280/dnet-openaire-users-1.0.0-SNAPSHOT/openid_connect_login",
"loginUrl" :"http://rudie.di.uoa.gr:8080/dnet-login/openid_connect_login",
"userInfoUrl" : "http://rudie.di.uoa.gr:8280/dnet-openaire-users-1.0.0-SNAPSHOT/api/users/getUserInfo?accessToken=",
"userInfoUrl" : "http://scoobydoo.di.uoa.gr:8080/dnet-openaire-users-1.0.0-SNAPSHOT/api/users/getUserInfo?accessToken=",
"logoutUrl" :"https://aai.openaire.eu/proxy/saml2/idp/SingleLogoutService.php?ReturnTo=",