plugins-functionality #43

Merged
argiro.kokogiannaki merged 86 commits from plugins-functionality into develop 2024-06-13 09:14:22 +02:00
128 changed files with 6210 additions and 112 deletions

View File

@ -0,0 +1,69 @@
<ng-template #card let-organization="organization" let-fullView="fullView">
<div [class]="fullView?'uk-card-body uk-height-1-1 uk-flex uk-flex-column uk-flex-around':''">
<div class="affiliation-logo">
<img *ngIf="organization.logo_url"
[src]="organization.logo_url | urlPrefix"
alt="{{(organization.name)?organization.name:''}} logo"
class="uk-blend-multiply uk-height-max-xsmall" loading="lazy">
</div>
<div class="affiliation-name multi-line-ellipsis lines-3" *ngIf="organization.name && fullView">
<p class="uk-text-emphasis uk-text-bold uk-margin-remove">
{{organization.name}}
</p>
</div>
</div>
</ng-template>
<ng-container *ngIf="affiliations.length > 0">
<div *ngIf="showLoading" class="uk-animation-fade uk-width-1-1" role="alert">
<span class="loading-gif uk-align-center"></span>
</div>
<div *ngIf="longView"
class="uk-child-width-1-5@xl uk-child-width-1-4@l uk-child-width-1-3@m uk-child-width-1-2@s uk-text-center uk-grid"
uk-height-match="target: .affiliation-logo, .affiliation-name"
uk-scrollspy="cls: uk-animation-fade; target: .uk-card; repeat: false"
uk-grid>
<div *ngFor="let affiliation of affiliations;">
<div>
<div class="uk-card uk-card-default uk-card-hover affiliationCard">
<a *ngIf="affiliation.website_url" target="_blank" [href]="affiliation.website_url | urlPrefix" class="uk-link-reset">
<ng-container *ngTemplateOutlet="card; context: { organization: affiliation, fullView: true}"></ng-container>
</a>
<span *ngIf="!affiliation.website_url" class="uk-link-reset">
<ng-container *ngTemplateOutlet="card; context: { organization: affiliation, fullView: true}"></ng-container>
</span>
</div>
</div>
</div>
</div>
<div *ngIf="affiliations.length > 0 && communityFirstPage && !longView" class="uk-grid uk-grid-large" uk-grid>
<div class="uk-width-auto@m uk-width-1-1@s">
<h2 class="uk-h1">
Supporting <br> Organizations
</h2>
<a class="uk-display-inline-block uk-text-uppercase uk-button uk-button-text uk-text-default uk-margin-top"
routerLinkActive="router-link-active" routerLink="/organizations">
<span class="uk-flex uk-flex-middle">
<span>Browse all</span>
</span>
</a>
</div>
<div class="uk-width-expand@m uk-width-1-1@s">
<div class="uk-grid uk-grid-large uk-child-width-1-3@m uk-child-width-1-2@s supportingOrganizations" uk-grid>
<div *ngFor="let affiliation of affiliations.slice(0,9);">
<a *ngIf="affiliation.website_url" target="_blank" [href]="affiliation.website_url | urlPrefix" class="uk-link-reset">
<ng-container *ngTemplateOutlet="card; context: {organization: affiliation, fullView: false}"></ng-container>
</a>
<span *ngIf="!affiliation.website_url" class="uk-link-reset">
<ng-container *ngTemplateOutlet="card; context: {organization: affiliation, fullView: false}"></ng-container>
</span>
</div>
</div>
</div>
</div>
</ng-container>
<!--<div *ngIf="affiliations.length == 0 && longView" class="uk-animation-fade uk-alert uk-alert-primary" role="alert">-->
<!-- No affiliations available-->
<!--</div>-->

View File

@ -0,0 +1,18 @@
.affiliationCard {
width: 260px !important;
height: 260px !important;
}
.supportingOrganizations a {
img, svg {
-webkit-filter: grayscale(1);
filter: grayscale(1);
transition-duration: 0.3s;
}
&:hover img, svg {
-webkit-filter: grayscale(0);
filter: grayscale(0);
transition-duration: 0.3s;
}
}

View File

@ -0,0 +1,68 @@
import {Component, Input} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {EnvProperties} from '../../utils/properties/env-properties';
import {AffiliationService} from "./affiliation.service";
import {Affiliation} from "../../utils/entities/CuratorInfo";
import {ConnectHelper} from "../connectHelper";
import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {ConfigurationService} from "../../utils/configuration/configuration.service";
import {CommunityService} from "../community/community.service";
@Component({
selector: 'affiliations',
templateUrl: './affiliations.component.html',
styleUrls: ['./affiliations.component.less']
})
export class AffiliationsComponent {
@Input() getAffiliationsFromAPI: boolean = false;
@Input() longView: boolean = false;
@Input() communityFirstPage: boolean = false;
@Input() affiliationsInSlider: number = 5;
@Input() affiliations: Affiliation[] = [];
@Input() sliderOptions = '';
@Input() arrows = true;
public showLoading: boolean = false;
public communityId: string;
public properties: EnvProperties = properties;
private subscriptions = [];
constructor(private route: ActivatedRoute, private affiliationService: AffiliationService, private config: ConfigurationService) {
}
public ngOnInit() {
this.subscriptions.push(this.config.portalAsObservable.subscribe(
res => {
// this.portal = res;
this.communityId = res.pid
},
error => {
console.log(error);
}
));
if (this.getAffiliationsFromAPI) {
this.showLoading = true;
this.affiliationService.initAffiliations(this.communityId);
this.subscriptions.push(this.affiliationService.affiliations.subscribe(
affiliations => {
this.affiliations = affiliations.filter((affiliation) => this.longView || !!affiliation['logo_url']);
this.showLoading = false;
},
error => {
console.error("Affiliations Component: Error getting affiliations for community with id: " + this.communityId, error);
this.showLoading = false;
}
));
}
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
this.affiliationService.clearSubscriptions();
}
}

View File

@ -0,0 +1,26 @@
import {NgModule} from '@angular/core';
import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard';
import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'
import {RouterModule} from '@angular/router';
import {AffiliationsComponent} from './affiliations.component';
import {CommonModule} from "@angular/common";
import {UrlPrefixModule} from "../../utils/pipes/url-prefix.module";
import {AffiliationService} from "./affiliation.service";
@NgModule({
imports: [
CommonModule, RouterModule, UrlPrefixModule
],
declarations: [
AffiliationsComponent
],
providers:[PreviousRouteRecorder, IsRouteEnabled, AffiliationService],
exports: [
AffiliationsComponent
]
})
export class AffiliationsModule{}

View File

@ -92,6 +92,8 @@ export class CommunityService {
const community: CommunityInfo = new CommunityInfo(); const community: CommunityInfo = new CommunityInfo();
community.title = resData.name; community.title = resData.name;
community.shortTitle = resData.shortName; community.shortTitle = resData.shortName;
community.displayTitle = resData.displayName?resData.displayName:resData.name;
community.displayShortTitle = resData.displayShortName?resData.displayShortName:resData.shortName;
community.communityId = resData.id; community.communityId = resData.id;
community.queryId = resData.queryId; community.queryId = resData.queryId;
community.logoUrl = resData.logoUrl; community.logoUrl = resData.logoUrl;
@ -102,6 +104,7 @@ export class CommunityService {
community.claim = resData.claim; community.claim = resData.claim;
community.membership = resData.membership; community.membership = resData.membership;
community.type = resData.type; community.type = resData.type;
community.plan = resData.plan?resData.plan:"Default";
community.otherZenodoCommunities = resData.otherZenodoCommunities; community.otherZenodoCommunities = resData.otherZenodoCommunities;
if (resData.hasOwnProperty('status')) { if (resData.hasOwnProperty('status')) {
community.status = resData.status; community.status = resData.status;

View File

@ -4,6 +4,8 @@ import {SelectionCriteria} from "../../utils/entities/contentProvider";
export class CommunityInfo { export class CommunityInfo {
title: string; title: string;
shortTitle:string; shortTitle:string;
displayTitle: string;
displayShortTitle:string;
communityId: string; communityId: string;
queryId: string; queryId: string;
type: string; type: string;
@ -24,6 +26,7 @@ export class CommunityInfo {
fos: string[] = []; fos: string[] = [];
sdg: string[] = [] sdg: string[] = []
selectionCriteria: SelectionCriteria; selectionCriteria: SelectionCriteria;
plan: "Standard" | "Advanced" | "Premium" | "National" | "Default" ;
public static checkIsUpload(response: CommunityInfo | CommunityInfo[]): any | any[] { public static checkIsUpload(response: CommunityInfo | CommunityInfo[]): any | any[] {
if (Array.isArray(response)) { if (Array.isArray(response)) {

View File

@ -0,0 +1,15 @@
import { NgModule} from '@angular/core';
import { RouterModule } from '@angular/router';
import {CuratorsComponent} from "./curators.component";
import {IsRouteEnabled} from "../../../error/isRouteEnabled.guard";
import {PreviousRouteRecorder} from "../../../utils/piwik/previousRouteRecorder.guard";
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', component: CuratorsComponent, canActivate: [IsRouteEnabled], canDeactivate: [PreviousRouteRecorder]}
])
]
})
export class CuratorsRoutingModule {
}

View File

@ -0,0 +1,152 @@
<schema2jsonld *ngIf="url" [URL]="url" [name]="pageTitle" type="other"></schema2jsonld>
<ng-container *ngIf="longView else shortView">
<div style="min-height: 650px;">
<div class="uk-container uk-container-large uk-section uk-section-small uk-padding-remove-bottom">
<div class="uk-padding-small uk-padding-remove-horizontal">
<breadcrumbs [breadcrumbs]="breadcrumbs"></breadcrumbs>
</div>
</div>
<div class="uk-container uk-container-large uk-section uk-section-small">
<div *ngIf="showLoading" class="uk-margin-large uk-padding-large uk-padding-remove-horizontal">
<loading></loading>
</div>
<div *ngIf="!showLoading">
<h1 class="uk-margin-top">
Curators
</h1>
<div *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0" class="uk-margin-medium">
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0"
[texts]="pageContents['top']">
</helper>
</div>
<div *ngIf="curators" class="uk-margin-large-top">
<div *ngFor="let curator of curators let i=index;" class="uk-card uk-card-default uk-padding uk-margin-medium-bottom">
<div class="uk-grid" uk-grid>
<div class="uk-width-2-3@m uk-flex uk-flex-middle">
<div class="uk-width-small">
<img *ngIf="curator.photo && curator.photo !== ''" class="uk-border-circle" style="width: 150px; height: 150px;"
src="{{downloadUrl + curator.photo}}" alt="Curator Photo">
<img *ngIf="!curator.photo || curator.photo == ''" class="uk-border-circle" style="width: 150px; height: 150px;"
src="../../assets/common-assets/curator-default.png" alt="Curator Photo">
</div>
<div class="uk-width-expand">
<div class="uk-padding">
<h4 class="uk-margin-remove">{{curator.name}}</h4>
<div *ngIf="curator.bio" class="uk-margin-top uk-height-max-large uk-overflow-auto">
<div class="uk-text-muted uk-margin-small-bottom">
Biography
</div>
<div>
<div *ngIf="!viewingMore">{{format(curator.bio)}}</div>
<div *ngIf="viewingMore">{{curator.bio}}</div>
<div *ngIf="curator.bio.length >= maxCharacters" class="uk-text-right uk-margin-small-top">
<a *ngIf="curator.bio.length >= maxCharacters"
(click)="openFsModal(curator)">
View details
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div *ngIf="curator.affiliations && curator.affiliations.length > 0" class="uk-width-1-3@m uk-padding" style="border-left: 1px solid #eaeaea">
<div class="uk-text-muted uk-margin-bottom">
Affiliations
</div>
<div class="uk-grid uk-flex-middle uk-child-width-1-2" uk-grid>
<div *ngFor="let affiliation of curator.affiliations">
<span *ngIf="!affiliation.website_url">
<img [src]="affiliation.logo_url | urlPrefix" [alt]="affiliation.name">
</span>
<a *ngIf="affiliation.website_url"
target="_blank" [href]="affiliation.website_url | urlPrefix">
<img [src]="affiliation.logo_url | urlPrefix" [alt]="affiliation.name">
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-margin-medium">
<helper *ngIf="pageContents && pageContents['bottom'] && pageContents['bottom'].length > 0"
[texts]="pageContents['bottom']">
</helper>
</div>
</div>
</div>
</ng-container>
<!-- Short view for community's homepage -->
<ng-template #shortView>
<div *ngIf="curators && curators.length > 0" class="uk-grid" uk-grid>
<span class="uk-width-auto">
Curated by:
</span>
<div class="uk-width-expand uk-padding-remove uk-overflow-auto">
<div class="uk-height-max-medium uk-margin-xsmall-left">
<a routerLink="/curators">
<span *ngFor="let curator of curators.slice(0,curatorsLimit) let i=index;">
{{curator.name}}
<span *ngIf="i < curators.length-1 && i < curatorsLimit-1">, </span>
</span>
<span *ngIf="curators.length > curatorsLimit">
+{{curators.length-curatorsLimit}} more
</span>
</a>
</div>
</div>
</div>
</ng-template>
<fs-modal #fsModal classTitle="">
<div *ngIf="curatorInModal" class="uk-width-1-1 uk-height-1-1">
<div class="uk-container uk-container-large uk-section">
<div class="uk-margin-large-top uk-grid uk-grid-large" uk-grid>
<div class="uk-width-1-3@m">
<h2>
{{curatorInModal.name}}
</h2>
<img *ngIf="curatorInModal.photo && curatorInModal.photo !== ''" class="uk-width-2-3 uk-border-circle uk-margin-top uk-margin-bottom"
src="{{downloadUrl + curatorInModal.photo}}" alt="Curator Photo">
<img *ngIf="!curatorInModal.photo || curatorInModal.photo == ''" class="uk-width-2-3 uk-border-circle uk-margin-top uk-margin-bottom"
src="../../assets/common-assets/curator-default.png" alt="Curator Photo">
</div>
<div class="uk-width-2-3@m">
<ul class="uk-tab" uk-tab>
<li>
<a>Biography</a>
</li>
<li *ngIf="curatorInModal.affiliations && curatorInModal.affiliations.length > 0">
<a>Affiliations</a>
</li>
</ul>
<ul class="uk-switcher">
<li class="uk-padding uk-padding-remove-left">
<h5>
Biography
</h5>
<div>
{{curatorInModal.bio}}
</div>
</li>
<li *ngIf="curatorInModal.affiliations && curatorInModal.affiliations.length > 0" class="uk-padding uk-padding-remove-left">
<div class="uk-grid uk-flex-middle uk-child-width-1-3" uk-grid>
<div *ngFor="let affiliation of curatorInModal.affiliations">
<span *ngIf="!affiliation.website_url">
<img [src]="affiliation.logo_url | urlPrefix" [alt]="affiliation.name">
</span>
<a *ngIf="affiliation.website_url"
target="_blank" [href]="affiliation.website_url | urlPrefix">
<img [src]="affiliation.logo_url | urlPrefix" [alt]="affiliation.name">
</a>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</fs-modal>

View File

@ -0,0 +1,155 @@
import {Component, Input, ViewChild} from '@angular/core';
import {EnvProperties} from '../../../utils/properties/env-properties';
import {CuratorService} from "../../curators/curator.service";
import {Curator} from "../../../utils/entities/CuratorInfo";
import {ActivatedRoute, Router} from "@angular/router";
import {CommunityService} from "../../community/community.service";
import {HelperService} from "../../../utils/helper/helper.service";
import {Meta, Title} from "@angular/platform-browser";
import {SEOService} from "../../../sharedComponents/SEO/SEO.service";
import {PiwikService} from "../../../utils/piwik/piwik.service";
import {Breadcrumb} from "../../../utils/breadcrumbs/breadcrumbs.component";
import {Subscription} from "rxjs";
import {properties} from "../../../../../environments/environment";
import {UserRegistryService} from "../../../services/user-registry.service";
import {FullScreenModalComponent} from '../../../utils/modal/full-screen-modal/full-screen-modal.component';
import {CommunityInfo} from "../../community/communityInfo";
@Component({
selector: 'curators',
templateUrl: './curators.component.html'
})
export class CuratorsComponent {
@Input() longView = true;
community: CommunityInfo;
public downloadUrl = null;
public showLoading = true;
public curators: Curator[] = [];
public curatorsLimit: number = 5;
public numberOfCurators: number = 5;
public showMore = [];
public maxCharacters = 450;
public viewingMore: boolean = false;
public curatorInModal;
public properties: EnvProperties;
public pageContents = null;
public divContents = null;
public url: string = null;
public pageTitle: string = "Curators";
public breadcrumbs: Breadcrumb[] = [{name: 'Home', route: '/'}, {name: 'About - Curators'}];
subs: Subscription[] = [];
@ViewChild('fsModal', { static: true }) fsModal: FullScreenModalComponent;
constructor(private route: ActivatedRoute,
private curatorsService: CuratorService,
private communityService: CommunityService,
private userRegistryService: UserRegistryService,
private _router: Router,
private helper: HelperService,
private _meta: Meta,
private _title: Title,
private seoService: SEOService,
private _piwikService: PiwikService) {
}
ngOnInit() {
this.showLoading = true;
this.properties = properties;
this.downloadUrl = this.properties.utilsService + '/download/';
//if (properties.environment !== 'development') {
if (!this.longView) {
this.subs.push(this.communityService.getCommunityAsObservable().subscribe(community => {
if (community) {
this.community = community;
this.getCurators();
}
}));
} else {
this.subs.push(this.communityService.getCommunityAsObservable().subscribe(community => {
if (community) {
this.community = community;
this.subs.push(this._piwikService.trackView(this.properties, this.pageTitle).subscribe());
this.url = this.properties.domain + this._router.url;
this.seoService.createLinkForCanonicalURL(this.url);
this.updateUrl(this.url);
this.updateTitle(this.pageTitle);
this.updateDescription("OpenAIRE - Connect, Community Gateway, research community");
//this.getDivContents();
this.getPageContents();
this.getCurators();
}
}));
}
}
ngOnDestroy() {
for (let sub of this.subs) {
sub.unsubscribe();
}
}
private getCurators() {
this.subs.push(this.curatorsService.getCurators(this.properties, this.community.communityId).subscribe(curators => {
this.curators = curators;
this.showLoading = false;
}, error => {
console.error(error);
this.curators = [];
this.showLoading = false;
}));
}
private getPageContents() {
this.subs.push(this.helper.getPageHelpContents(this.properties, this.community.communityId, this._router.url).subscribe(contents => {
this.pageContents = contents;
}));
}
private getDivContents() {
this.subs.push(this.helper.getDivHelpContents(this.properties, this.community.communityId, this._router.url).subscribe(contents => {
this.divContents = contents;
}));
}
format(name: string) {
if (name) {
return (((name).length > this.maxCharacters) ? (name.substring(0, (this.maxCharacters - ('...').length)) + '...') : name);
} else {
return null;
}
}
public viewMore() {
this.viewingMore = !this.viewingMore;
}
public openFsModal(curator) {
this.curatorInModal = curator;
this.fsModal.title = this.community.shortTitle + ' Curator';
this.fsModal.open();
}
private updateDescription(description: string) {
this._meta.updateTag({content: description}, "name='description'");
this._meta.updateTag({content: description}, "property='og:description'");
}
private updateTitle(title: string) {
var _title = ((title.length > 50) ? title.substring(0, 50) : title);
this._title.setTitle(_title);
this._meta.updateTag({content: _title}, "property='og:title'");
}
private updateUrl(url: string) {
this._meta.updateTag({content: url}, "property='og:url'");
}
}

View File

@ -0,0 +1,35 @@
import { NgModule} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import {CuratorsComponent} from './curators.component';
import {CuratorService} from "../../curators/curator.service";
import {CuratorsRoutingModule} from "./curators-routing.module";
import {HelperModule} from "../../../utils/helper/helper.module";
import {Schema2jsonldModule} from "../../../sharedComponents/schema2jsonld/schema2jsonld.module";
import {SEOServiceModule} from "../../../sharedComponents/SEO/SEOService.module";
import {PiwikServiceModule} from "../../../utils/piwik/piwikService.module";
import {BreadcrumbsModule} from "../../../utils/breadcrumbs/breadcrumbs.module";
import {UrlPrefixModule} from "../../../utils/pipes/url-prefix.module";
import {LoadingModule} from '../../../utils/loading/loading.module';
import {FullScreenModalModule} from '../../../utils/modal/full-screen-modal/full-screen-modal.module';
import {AffiliationsModule} from "../../affiliations/affiliations.module";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule,
CuratorsRoutingModule, AffiliationsModule, HelperModule,
Schema2jsonldModule, SEOServiceModule, PiwikServiceModule,
BreadcrumbsModule, UrlPrefixModule, LoadingModule,
FullScreenModalModule
],
declarations: [
CuratorsComponent
],
providers: [CuratorService],
exports: [
CuratorsComponent
]
})
export class CuratorsModule {}

View File

@ -6,13 +6,13 @@ import {map} from "rxjs/operators";
@Injectable() @Injectable()
export class SearchCommunityDataprovidersService { export class SearchCommunityDataprovidersService {
constructor(private http: HttpClient ) {} constructor(private http: HttpClient ) {}
searchDataproviders (properties:EnvProperties, pid: string):any { searchDataproviders (properties:EnvProperties, pid: string, deposit = false):any {
let url = properties.communityAPI+pid+"/contentproviders"; let url = properties.communityAPI+pid+"/datasources" + (deposit?'?deposit=true':'');
return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url); return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url);
} }
countTotalDataproviders(properties:EnvProperties,pid:string) { countTotalDataproviders(properties:EnvProperties,pid:string) {
let url = properties.communityAPI+pid+"/contentproviders"; let url = properties.communityAPI+pid+"/datasources";
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url) return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
.pipe(map(res => res['length'])); .pipe(map(res => res['length']));
} }

View File

@ -42,7 +42,7 @@ export class ZenodoCommunitiesService {
var result: ZenodoCommunityInfo = new ZenodoCommunityInfo(); var result: ZenodoCommunityInfo = new ZenodoCommunityInfo();
let metadata = resData["metadata"]; let metadata = resData["metadata"];
result['title'] = metadata.title; result['title'] = metadata.title;
result['id'] = resData.id; result['id'] = resData.slug;
result['description'] = metadata.description; result['description'] = metadata.description;
result['link'] = resData.links.self_html; result['link'] = resData.links.self_html;
result['logoUrl'] = resData.links.logo; result['logoUrl'] = resData.links.logo;

View File

@ -6,4 +6,5 @@ export class ZenodoCommunityInfo {
logoUrl: string; logoUrl: string;
date: Date; date: Date;
page: string; page: string;
master:boolean = false;
} }

View File

@ -143,7 +143,7 @@ export class DivIdsComponent implements OnInit {
this.deleteDivIdsFromArray(this.selectedDivIds); this.deleteDivIdsFromArray(this.selectedDivIds);
NotificationHandler.rise('Classes have been <b>successfully deleted</b>'); NotificationHandler.rise('Classes have been <b>successfully deleted</b>');
this.showLoading = false; this.showLoading = false;
this._clearCacheService.clearCache("Class ids deleted"); //this._clearCacheService.clearCache("Class ids deleted");
}, },
error => this.handleUpdateError('System error deleting the selected classes', error) error => this.handleUpdateError('System error deleting the selected classes', error)
)); ));
@ -195,7 +195,7 @@ export class DivIdsComponent implements OnInit {
divId => { divId => {
this.divIdSavedSuccessfully(divId); this.divIdSavedSuccessfully(divId);
NotificationHandler.rise('Class <b>' + divId.name + '</b> has been <b>successfully created</b>'); NotificationHandler.rise('Class <b>' + divId.name + '</b> has been <b>successfully created</b>');
this._clearCacheService.clearCache("Class id saved"); //this._clearCacheService.clearCache("Class id saved");
}, },
error => this.handleUpdateError("System error creating class", error) error => this.handleUpdateError("System error creating class", error)
)); ));
@ -204,7 +204,7 @@ export class DivIdsComponent implements OnInit {
divId => { divId => {
this.divIdUpdatedSuccessfully(divId); this.divIdUpdatedSuccessfully(divId);
NotificationHandler.rise('Class <b>' + divId.name + '</b> has been <b>successfully updated</b>'); NotificationHandler.rise('Class <b>' + divId.name + '</b> has been <b>successfully updated</b>');
this._clearCacheService.clearCache("Class id updated"); //this._clearCacheService.clearCache("Class id updated");
}, },
error => this.handleUpdateError("System error updating class", error) error => this.handleUpdateError("System error updating class", error)
)); ));

View File

@ -166,7 +166,7 @@ export class ClassContentFormComponent implements OnInit {
this._router.navigate(['../'], {queryParams: {"pageId": this.pageId}, relativeTo: this.route}); this._router.navigate(['../'], {queryParams: {"pageId": this.pageId}, relativeTo: this.route});
NotificationHandler.rise('Page content has been <b>successfully updated</b>'); NotificationHandler.rise('Page content has been <b>successfully updated</b>');
this.showLoading = false; this.showLoading = false;
this._clearCacheService.clearCache("Class help text saved or updated"); this._clearCacheService.clearCacheInRoute("Class help text saved or updated",this.portal, this.page.route);
}, },
err => this.handleUpdateError('System error saving page content', err) err => this.handleUpdateError('System error saving page content', err)
)); ));

View File

@ -155,7 +155,7 @@ export class ClassHelpContentsComponent implements OnInit {
this.deletePageHelpContentsFromArray(this.selectedPageContents); this.deletePageHelpContentsFromArray(this.selectedPageContents);
NotificationHandler.rise('Page content(s) has been <b>successfully deleted</b>'); NotificationHandler.rise('Page content(s) has been <b>successfully deleted</b>');
this.showLoading = false; this.showLoading = false;
this._clearCacheService.clearCache("Class text texts deleted"); this._clearCacheService.clearCacheInRoute("Class text texts deleted",this.portal, this.page.route);
}, },
error => this.handleUpdateError('System error deleting the selected page content(s)', error) error => this.handleUpdateError('System error deleting the selected page content(s)', error)
)); ));
@ -198,7 +198,7 @@ export class ClassHelpContentsComponent implements OnInit {
this.countClassHelpContents(); this.countClassHelpContents();
this.applyCheck(false); this.applyCheck(false);
NotificationHandler.rise('Page content(s) has been <b>successfully updated</b>'); NotificationHandler.rise('Page content(s) has been <b>successfully updated</b>');
this._clearCacheService.clearCache("class help text's status changed"); this._clearCacheService.clearCacheInRoute("class help text's status changed",this.portal, this.page.route);
}, },
error => this.handleUpdateError('System error changing the status of the selected page content(s)', error) error => this.handleUpdateError('System error changing the status of the selected page content(s)', error)
)); ));

View File

@ -202,8 +202,8 @@ export class EntitiesComponent implements OnInit {
this.deleteEntitiesFromArray(this.selectedEntities); this.deleteEntitiesFromArray(this.selectedEntities);
NotificationHandler.rise('Entities have been <b>successfully deleted</b>'); NotificationHandler.rise('Entities have been <b>successfully deleted</b>');
this.showLoading = false; this.showLoading = false;
this._clearCacheService.clearCache("entities deleted"); // this._clearCacheService.clearCache("entities deleted");
this._clearCacheService.purgeBrowserCache("entities deleted", this.portal); // this._clearCacheService.purgeBrowserCache("entities deleted", this.portal);
}, },
error => this.handleUpdateError('System error deleting the selected entities', error) error => this.handleUpdateError('System error deleting the selected entities', error)
); );
@ -244,8 +244,8 @@ export class EntitiesComponent implements OnInit {
entity => { entity => {
this.entityUpdatedSuccessfully(entity); this.entityUpdatedSuccessfully(entity);
NotificationHandler.rise('Entity <b>' + entity.name + '</b> has been <b>successfully updated</b>'); NotificationHandler.rise('Entity <b>' + entity.name + '</b> has been <b>successfully updated</b>');
this._clearCacheService.clearCache("entity updated"); // this._clearCacheService.clearCache("entity updated");
this._clearCacheService.purgeBrowserCache("entity updated", this.portal); // this._clearCacheService.purgeBrowserCache("entity updated", this.portal);
}, },
error => this.handleUpdateError('System error updating entity', error) error => this.handleUpdateError('System error updating entity', error)
); );
@ -254,8 +254,8 @@ export class EntitiesComponent implements OnInit {
entity => { entity => {
this.entitySavedSuccessfully(entity); this.entitySavedSuccessfully(entity);
NotificationHandler.rise('Entity <b>' + entity.name + '</b> has been <b>successfully created</b>'); NotificationHandler.rise('Entity <b>' + entity.name + '</b> has been <b>successfully created</b>');
this._clearCacheService.clearCache("entity saved"); // this._clearCacheService.clearCache("entity saved");
this._clearCacheService.purgeBrowserCache("entity saved", this.portal) // this._clearCacheService.purgeBrowserCache("entity saved", this.portal)
}, },
error => this.handleUpdateError('System error creating entity', error) error => this.handleUpdateError('System error creating entity', error)
); );
@ -345,7 +345,7 @@ export class EntitiesComponent implements OnInit {
this.checkboxes[i].entity.isEnabled = this.toggleStatus; this.checkboxes[i].entity.isEnabled = this.toggleStatus;
} }
this.applyCheck(false); this.applyCheck(false);
this._clearCacheService.clearCache("entity's status changed"); this._clearCacheService.clearCacheInRoute("entity's status changed", this.portal, "/");
this._clearCacheService.purgeBrowserCache("entity's status changed", this.portal); this._clearCacheService.purgeBrowserCache("entity's status changed", this.portal);
}, },
error => this.handleUpdateError('System error changing the status of the selected entity(-ies)', error) error => this.handleUpdateError('System error changing the status of the selected entity(-ies)', error)

View File

@ -34,9 +34,9 @@
</div> </div>
<form *ngIf="!showLoading" [formGroup]="myForm"> <form *ngIf="!showLoading" [formGroup]="myForm">
<div class="uk-grid uk-child-width-1-2"> <div class="uk-grid uk-child-width-1-2">
<div *ngIf="placementsOptions.length > 0" input [formInput]="myForm.get('placement')" <div *ngIf="placementsOptions.length > 1 && myForm.get('placement').value" input [formInput]="myForm.get('placement')"
placeholder="Select placement" [options]="placementsOptions" type="select"></div> placeholder="Select placement" [options]="placementsOptions" type="select"></div>
<div input [formInput]="myForm.get('order')" placeholder="Select order" [options]="orderOptions" type="select"></div> <div *ngIf="orderOptions.length > 1 " input [formInput]="myForm.get('order')" placeholder="Select order" [options]="orderOptions" type="select"></div>
</div> </div>
<div class="form-group uk-margin-medium-top"> <div class="form-group uk-margin-medium-top">
<span class="uk-text-bold uk-margin-small-right">Select Status (Enable/ disable)</span> <span class="uk-text-bold uk-margin-small-right">Select Status (Enable/ disable)</span>

View File

@ -199,7 +199,7 @@ export class PageContentFormComponent implements OnInit {
NotificationHandler.rise('Page content has been <b>successfully ' + (this.pageContentId ? 'updated' : 'created') + '</b>'); NotificationHandler.rise('Page content has been <b>successfully ' + (this.pageContentId ? 'updated' : 'created') + '</b>');
this._router.navigate(['../'], {queryParams: {"pageId": this.pageId}, relativeTo: this.route}); this._router.navigate(['../'], {queryParams: {"pageId": this.pageId}, relativeTo: this.route});
this.showLoading = false; this.showLoading = false;
this._clearCacheService.clearCache("page help content saved"); this._clearCacheService.clearCacheInRoute("page help content saved",this.portal, this.page.route);
}, },
err => this.handleUpdateError('System error saving page content', err) err => this.handleUpdateError('System error saving page content', err)
)); ));

View File

@ -165,7 +165,7 @@ export class PageHelpContentsComponent implements OnInit {
this.deletePageHelpContentsFromArray(this.selectedPageContents); this.deletePageHelpContentsFromArray(this.selectedPageContents);
NotificationHandler.rise('Page content(s) has been <b>successfully deleted</b>'); NotificationHandler.rise('Page content(s) has been <b>successfully deleted</b>');
this.showLoading = false; this.showLoading = false;
this._clearCacheService.clearCache("Help texts deleted"); this._clearCacheService.clearCacheInRoute("Help texts deleted",this.portal, this.page.route);
}, },
error => this.handleUpdateError('System error deleting the selected page content(s)', error) error => this.handleUpdateError('System error deleting the selected page content(s)', error)
)); ));
@ -210,7 +210,7 @@ export class PageHelpContentsComponent implements OnInit {
NotificationHandler.rise('Page content(s) has been <b>successfully updated</b>'); NotificationHandler.rise('Page content(s) has been <b>successfully updated</b>');
this.countPageHelpContents(); this.countPageHelpContents();
this.applyCheck(false); this.applyCheck(false);
this._clearCacheService.clearCache("Help text's status changed"); this._clearCacheService.clearCacheInRoute("Help text's status changed",this.portal, this.page.route);
}, },
error => this.handleUpdateError('System error changing the status of the selected page content(s)', error) error => this.handleUpdateError('System error changing the status of the selected page content(s)', error)
)); ));

View File

@ -271,8 +271,8 @@ export class MenuComponent implements OnInit {
this.deleteMenuItemFromArray(this.selectedMenuItem, this.isChild); this.deleteMenuItemFromArray(this.selectedMenuItem, this.isChild);
NotificationHandler.rise("Menu item have been <b>successfully deleted</b>"); NotificationHandler.rise("Menu item have been <b>successfully deleted</b>");
this.showLoading = false; this.showLoading = false;
this._clearCacheService.clearCache("Menu item deleted"); this._clearCacheService.clearCacheInRoute("Menu item deleted",this.portal, "/");
this._clearCacheService.purgeBrowserCache("Menu item deleted", this.portal);
}, },
error => this.handleError("Server error deleting menu item", error) error => this.handleError("Server error deleting menu item", error)
) )
@ -313,8 +313,7 @@ export class MenuComponent implements OnInit {
menuItem => { menuItem => {
this.menuItemSavedSuccessfully(menuItem, true); this.menuItemSavedSuccessfully(menuItem, true);
NotificationHandler.rise('Menu item <b>' + menuItem.title + '</b> has been <b>successfully created</b>'); NotificationHandler.rise('Menu item <b>' + menuItem.title + '</b> has been <b>successfully created</b>');
this._clearCacheService.clearCache("Menu item saved"); this._clearCacheService.clearCacheInRoute("Menu item saved",this.portal, "/");
this._clearCacheService.purgeBrowserCache("Menu item saved", this.portal);
}, },
error => this.handleError("System error creating menu item", error) error => this.handleError("System error creating menu item", error)
) )
@ -325,8 +324,7 @@ export class MenuComponent implements OnInit {
menuItem => { menuItem => {
this.menuItemSavedSuccessfully(menuItem, false); this.menuItemSavedSuccessfully(menuItem, false);
NotificationHandler.rise('Menu item <b>' + menuItem.title + '</b> has been <b>successfully updated</b>'); NotificationHandler.rise('Menu item <b>' + menuItem.title + '</b> has been <b>successfully updated</b>');
this._clearCacheService.clearCache("Menu item updated"); this._clearCacheService.clearCacheInRoute("Menu item updated",this.portal, "/");
this._clearCacheService.purgeBrowserCache("Menu item updated", this.portal);
}, },
error => this.handleError("System error updating menu item", error) error => this.handleError("System error updating menu item", error)
) )
@ -392,8 +390,7 @@ export class MenuComponent implements OnInit {
HelperFunctions.swap(temp, index, newIndex); HelperFunctions.swap(temp, index, newIndex);
this._helpContentService.reorderMenuItems(temp, this.portal).subscribe(() => { this._helpContentService.reorderMenuItems(temp, this.portal).subscribe(() => {
HelperFunctions.swap(this.featuredMenuItems, index, newIndex); HelperFunctions.swap(this.featuredMenuItems, index, newIndex);
this._clearCacheService.clearCache("Menu items reordered"); this._clearCacheService.clearCacheInRoute("Menu items reordered",this.portal, "/");
this._clearCacheService.purgeBrowserCache("Menu items reordered", this.portal);
}, error => { }, error => {
this.handleError("System error reordering menu items", error); this.handleError("System error reordering menu items", error);
}); });
@ -405,8 +402,7 @@ export class MenuComponent implements OnInit {
HelperFunctions.swap(temp, index, newIndex); HelperFunctions.swap(temp, index, newIndex);
this._helpContentService.reorderMenuItems(temp, this.portal).subscribe(() => { this._helpContentService.reorderMenuItems(temp, this.portal).subscribe(() => {
HelperFunctions.swap(children && children.length ? children : this.normalMenuItems, index, newIndex); HelperFunctions.swap(children && children.length ? children : this.normalMenuItems, index, newIndex);
this._clearCacheService.clearCache("Menu items reordered"); this._clearCacheService.clearCacheInRoute("Menu items reordered",this.portal, "/");
this._clearCacheService.purgeBrowserCache("Menu items reordered", this.portal);
}, error => { }, error => {
this.handleError("System error reordering menu items", error); this.handleError("System error reordering menu items", error);
}); });
@ -421,8 +417,7 @@ export class MenuComponent implements OnInit {
} else { } else {
this.showNormalMenu = status; this.showNormalMenu = status;
} }
this._clearCacheService.clearCache("Menu toggled"); this._clearCacheService.clearCacheInRoute("Menu toggled",this.portal, "/");
this._clearCacheService.purgeBrowserCache("Menu toggled", this.portal);
NotificationHandler.rise("Menu has been <b>successfully toggled to be "+(status?"visible":"hidden")+"</b>"); NotificationHandler.rise("Menu has been <b>successfully toggled to be "+(status?"visible":"hidden")+"</b>");
}, error => { }, error => {
this.handleError("System error toggling menu", error); this.handleError("System error toggling menu", error);
@ -434,8 +429,7 @@ export class MenuComponent implements OnInit {
this.subscriptions.push( this.subscriptions.push(
this._helpContentService.alignMenu(MenuAlignment[alignment], this.portal).subscribe(() => { this._helpContentService.alignMenu(MenuAlignment[alignment], this.portal).subscribe(() => {
this.featuredAlignment = alignment; this.featuredAlignment = alignment;
this._clearCacheService.clearCache("Menu aligned"); this._clearCacheService.clearCacheInRoute("Menu aligned",this.portal, "/");
this._clearCacheService.purgeBrowserCache("Menu aligned", this.portal);
NotificationHandler.rise("Menu has been <b>successfully "+alignment.toLowerCase()+" aligned</b>"); NotificationHandler.rise("Menu has been <b>successfully "+alignment.toLowerCase()+" aligned</b>");
}, error => { }, error => {
this.handleError("System error aligning menu to the "+alignment.toLowerCase(), error); this.handleError("System error aligning menu to the "+alignment.toLowerCase(), error);

View File

@ -88,14 +88,23 @@
<div class="uk-card-footer uk-padding-remove-vertical"> <div class="uk-card-footer uk-padding-remove-vertical">
<div class="uk-grid uk-grid-small uk-flex-nowrap uk-grid-divider uk-flex-right" uk-grid> <div class="uk-grid uk-grid-small uk-flex-nowrap uk-grid-divider uk-flex-right" uk-grid>
<ng-container *ngIf="!isPortalAdministrator"> <ng-container *ngIf="!isPortalAdministrator">
<div *ngIf="pagePluginTemplatesCount[check.page._id]>0" >
<div class="uk-padding-small uk-padding-remove-horizontal">
<a class="uk-button uk-button-link uk-text-truncate"
[queryParams]="{pageId: check.page._id}"
routerLink="../plugins">
Manage plugins
<span *ngIf="pagePluginTemplatesCount[check.page._id]">({{pagePluginTemplatesCount[check.page._id]}})</span>
</a>
</div>
</div>
<div *ngIf="check.page.top || check.page.bottom || check.page.left || check.page.right"> <div *ngIf="check.page.top || check.page.bottom || check.page.left || check.page.right">
<div class="uk-padding-small uk-padding-remove-horizontal"> <div class="uk-padding-small uk-padding-remove-horizontal">
<a class="uk-button uk-button-link uk-text-truncate" <a class="uk-button uk-button-link uk-text-truncate"
[queryParams]="{pageId: check.page._id}" [queryParams]="{pageId: check.page._id}"
routerLink="../helptexts"> routerLink="../helptexts">
Manage page help texts Manage page help texts
<span *ngIf="pageHelpContentsCount[check.page._id]">({{pageHelpContentsCount[check.page._id]}} <span *ngIf="pageHelpContentsCount[check.page._id]">({{pageHelpContentsCount[check.page._id]}})</span>
)</span>
</a> </a>
</div> </div>
</div> </div>
@ -105,8 +114,7 @@
[queryParams]="{ pageId: check.page._id}" [queryParams]="{ pageId: check.page._id}"
routerLink="../classContents">Manage class help texts routerLink="../classContents">Manage class help texts
<span <span
*ngIf="pageClassContentsCount[check.page._id]">({{pageClassContentsCount[check.page._id]}} *ngIf="pageClassContentsCount[check.page._id]">({{pageClassContentsCount[check.page._id]}})</span>
)</span>
</a> </a>
</div> </div>
</div> </div>
@ -122,6 +130,16 @@
</ng-container> </ng-container>
<ng-container <ng-container
*ngIf="isPortalAdministrator || (check.page.portalType == properties.adminToolsPortalType && check.page.portalPid == portal)"> *ngIf="isPortalAdministrator || (check.page.portalType == properties.adminToolsPortalType && check.page.portalPid == portal)">
<div *ngIf="pagePluginTemplatesCount[check.page._id]>0" >
<div class="uk-padding-small uk-padding-remove-horizontal">
<a class="uk-button uk-button-link uk-text-truncate"
[queryParams]="{pageId: check.page._id}"
routerLink="../templates">
Manage plugin templates {{check.page.portalPid}}
<span *ngIf="pagePluginTemplatesCount[check.page._id]">({{pagePluginTemplatesCount[check.page._id]}})</span>
</a>
</div>
</div>
<div> <div>
<div class="uk-padding-small uk-padding-remove-horizontal"> <div class="uk-padding-small uk-padding-remove-horizontal">
<button [disabled]="!portal && check.page.portalPid" <button [disabled]="!portal && check.page.portalPid"

View File

@ -20,6 +20,7 @@ import {Stakeholder} from "../../monitor/entities/stakeholder";
import {CommunityService} from "../../connect/community/community.service"; import {CommunityService} from "../../connect/community/community.service";
import {ClearCacheService} from "../../services/clear-cache.service"; import {ClearCacheService} from "../../services/clear-cache.service";
import {NotificationHandler} from "../../utils/notification-handler"; import {NotificationHandler} from "../../utils/notification-handler";
import {PluginsService} from "../../services/plugins.service";
@Component({ @Component({
selector: 'pages', selector: 'pages',
@ -68,10 +69,11 @@ export class PagesComponent implements OnInit {
private index: number; private index: number;
pageHelpContentsCount = {}; pageHelpContentsCount = {};
pageClassContentsCount = {}; pageClassContentsCount = {};
pagePluginTemplatesCount = {};
constructor(private element: ElementRef, private route: ActivatedRoute, constructor(private element: ElementRef, private route: ActivatedRoute,
private title: Title, private title: Title,
private _router: Router, private _helpContentService: HelpContentService, private _router: Router, private _helpContentService: HelpContentService,
private _pluginsService: PluginsService,
private userManagementService: UserManagementService, private _fb: UntypedFormBuilder, private userManagementService: UserManagementService, private _fb: UntypedFormBuilder,
private communityService: CommunityService, private communityService: CommunityService,
private stakeholderService: StakeholderService, private stakeholderService: StakeholderService,
@ -141,8 +143,9 @@ export class PagesComponent implements OnInit {
}, },
error => this.handleError('System error retrieving pages', error))); error => this.handleError('System error retrieving pages', error)));
if (this.portal) { if (this.portal) {
this.getPageHelpContentsCounts(this.portal); this.getCountsPerPID(this.portal);
} }
this.getPluginTemplatesContentsCounts()
} }
ngOnDestroy(): void { ngOnDestroy(): void {
@ -249,8 +252,8 @@ export class PagesComponent implements OnInit {
this.deletePagesFromArray(this.selectedPages); this.deletePagesFromArray(this.selectedPages);
NotificationHandler.rise('Pages have been <b>successfully deleted</b>'); NotificationHandler.rise('Pages have been <b>successfully deleted</b>');
this.showLoading = false; this.showLoading = false;
this._clearCacheService.clearCache("Pages deleted"); // this._clearCacheService.clearCache("Pages deleted");
this._clearCacheService.purgeBrowserCache("Pages deleted", this.portal); // this._clearCacheService.purgeBrowserCache("Pages deleted", this.portal);
}, },
error => this.handleUpdateError('System error deleting the selected pages', error) error => this.handleUpdateError('System error deleting the selected pages', error)
)); ));
@ -317,8 +320,8 @@ export class PagesComponent implements OnInit {
page => { page => {
this.pageSavedSuccessfully(page, true); this.pageSavedSuccessfully(page, true);
NotificationHandler.rise('Page <b>' + page.name + '</b> has been <b>successfully created</b>'); NotificationHandler.rise('Page <b>' + page.name + '</b> has been <b>successfully created</b>');
this._clearCacheService.clearCache("Page saved"); // this._clearCacheService.clearCache("Page saved");
this._clearCacheService.purgeBrowserCache("Page saved", this.portal); // this._clearCacheService.purgeBrowserCache("Page saved", this.portal);
}, },
error => this.handleUpdateError('System error creating page', error) error => this.handleUpdateError('System error creating page', error)
)); ));
@ -327,8 +330,8 @@ export class PagesComponent implements OnInit {
page => { page => {
this.pageSavedSuccessfully(page, false); this.pageSavedSuccessfully(page, false);
NotificationHandler.rise('Page <b>' + page.name + '</b> has been <b>successfully updated</b>'); NotificationHandler.rise('Page <b>' + page.name + '</b> has been <b>successfully updated</b>');
this._clearCacheService.clearCache("Page updated"); // this._clearCacheService.clearCache("Page updated");
this._clearCacheService.purgeBrowserCache("Page updated", this.portal); // this._clearCacheService.purgeBrowserCache("Page updated", this.portal);
}, },
error => this.handleUpdateError('System error updating page', error) error => this.handleUpdateError('System error updating page', error)
)); ));
@ -412,7 +415,7 @@ export class PagesComponent implements OnInit {
this.checkboxes[i].page.isEnabled = status; this.checkboxes[i].page.isEnabled = status;
} }
this.applyCheck(false); this.applyCheck(false);
this._clearCacheService.clearCache("Page's status changed"); this._clearCacheService.clearCacheInRoute("Page's status changed",this.portal, "/");
this._clearCacheService.purgeBrowserCache("Page's status changed", this.portal); this._clearCacheService.purgeBrowserCache("Page's status changed", this.portal);
}, },
error => this.handleUpdateError('System error changing the status of the selected page(s)', error) error => this.handleUpdateError('System error changing the status of the selected page(s)', error)
@ -426,7 +429,7 @@ export class PagesComponent implements OnInit {
} }
} }
getPageHelpContentsCounts(community_pid: string) { getCountsPerPID(community_pid: string) {
this.subscriptions.push(this._helpContentService.countCommunityPageHelpContents(community_pid, this.properties.adminToolsAPIURL, false).subscribe( this.subscriptions.push(this._helpContentService.countCommunityPageHelpContents(community_pid, this.properties.adminToolsAPIURL, false).subscribe(
pageHelpContentsCount => { pageHelpContentsCount => {
this.pageHelpContentsCount = pageHelpContentsCount; this.pageHelpContentsCount = pageHelpContentsCount;
@ -437,5 +440,19 @@ export class PagesComponent implements OnInit {
this.pageClassContentsCount = pageClassContentsCount; this.pageClassContentsCount = pageClassContentsCount;
}, },
error => this.handleError('System error retrieving page contents', error))); error => this.handleError('System error retrieving page contents', error)));
this.subscriptions.push(this._pluginsService.countPluginTemplatePerPage( this.properties.adminToolsAPIURL, community_pid).subscribe(
countPlugins => {
this.pagePluginTemplatesCount = countPlugins;
},
error => this.handleError('System error retrieving page contents', error)));
} }
getPluginTemplatesContentsCounts() {
this.subscriptions.push(this._pluginsService.countPluginTemplatePerPageForAllPortals( this.properties.adminToolsAPIURL).subscribe(
countPlugins => {
this.pagePluginTemplatesCount = countPlugins;
},
error => this.handleError('System error retrieving page contents', error)));
}
} }

View File

@ -0,0 +1,144 @@
import {Component, Input, SimpleChanges} from '@angular/core';
import {PluginBaseFormComponent, PluginEditEvent} from "../../utils/base-plugin.form.component";
import {PluginCardInfo} from "./plugin-card-info.component";
@Component({
selector: 'plugin-card-info-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<ng-container *ngIf="selectedIndex == -1">
<plugin-field-edit [value]=" pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)"></plugin-field-edit>
<plugin-field-edit [value]=" pluginObject.description"
type="textarea" field="description" (changed)="valueChanged($event)"></plugin-field-edit>
<hr class="uk-margin-left">
<div class="uk-margin-top uk-text-muted">
Cards:
</div>
<ng-container *ngFor="let card of pluginObject.cardInfoArray; let i = index">
<div class="uk-grid uk-grid-small uk-margin-xsmall-top">
<div *ngIf="selectedIndex != i" class="uk-text-small uk-width-expand">
<plugin-field-edit [value]=" pluginObject.cardInfoArray[i].show" type="checkbox" field="cardInfoArray"
(editClicked)="pluginEditEvent = $event"
(changed)="cardShowChanged(i,$event)"></plugin-field-edit>
{{card.title}}
</div>
<div class="uk-padding-remove-left uk-margin-medium-right">
<button
class="uk-button uk-button-link uk-flex uk-flex-middle" (click)="edit(i)">
<icon name="edit" [flex]="true"></icon>
</button>
</div>
</div>
</ng-container>
</ng-container>
<ng-container *ngIf="selectedIndex > -1">
<div *ngIf="editTemplate" class="back uk-margin-bottom">
<a (click)="close()" class="uk-flex uk-flex-middle uk-flex-center">
<div class="uk-width-auto">
<icon name="west" ratio="1.3"
[flex]="true"></icon>
</div>
<span class="uk-text-small">Plugin Options</span>
</a>
</div>
<!--<div class="uk-text-small">
Enable
<plugin-field-edit [value]=" pluginObject.cardInfoArray[selectedIndex].show"
type="boolean" field="cardInfoArray" (editClicked)="pluginEditEvent = $event"
(changed)="cardShowChanged(selectedIndex,$event)">
</plugin-field-edit>
</div>-->
<div class="uk-margin-top">
<plugin-field-edit [value]="pluginObject.cardInfoArray[selectedIndex].title"
type="text" field="title"
(changed)="cardValueChanged(selectedIndex, $event)"></plugin-field-edit>
</div>
<div class="uk-margin-top">
<plugin-field-edit [value]=" pluginObject.cardInfoArray[selectedIndex].description"
type="textarea" field="description"
(changed)="cardValueChanged(selectedIndex, $event)"></plugin-field-edit>
</div>
<hr class="uk-margin-left">
<div class="uk-margin-top" title="Use material icons to update the card icon">
<div class="uk-width-1-1 uk-text-right">
<a href="https://fonts.google.com/icons" target="_blank" class="uk-text-xsmall uk-text-right custom-external">More options</a>
</div>
<plugin-field-edit [value]=" pluginObject.cardInfoArray[selectedIndex].icon"
type="text" field="icon" placeholder="Material icon"
(changed)="cardValueChanged(selectedIndex, $event)"></plugin-field-edit>
</div>
<ng-container *ngFor="let cardUrl of pluginObject.cardInfoArray[selectedIndex].urlsArray; let j = index ">
<div class=" uk-margin-top uk-text-meta uk-text-xsmall"> Link #{{j + 1}}</div>
<div class="uk-margin-small-top">
<plugin-field-edit [value]=" cardUrl.url"
type="text" field="url"
(changed)="cardUrlValueChanged(selectedIndex, j, $event)"></plugin-field-edit>
</div>
<div class="uk-margin-top">
<plugin-field-edit [value]=" cardUrl.linkText"
type="text" field="linkText" placeholder="Link text"
(changed)="cardUrlValueChanged(selectedIndex, j, $event)"></plugin-field-edit>
</div>
</ng-container>
</ng-container>
</div>
`,
})
export class PluginCardInfoFormComponent extends PluginBaseFormComponent<PluginCardInfo> {
selectedIndex = -1;
@Input() editSubmenuOpen;
constructor() {
super()
}
ngOnChanges(changes: SimpleChanges) {
if (this.editSubmenuOpen == false && this.selectedIndex > -1) {
this.close();
}
}
cardShowChanged(i, $event: PluginEditEvent) {
this.pluginObject.cardInfoArray[i].show = $event.value;
$event.value = this.pluginObject.cardInfoArray;
this.valuesChanged.emit({field: $event.field, value: $event.value, type: 'parent'})
}
cardValueChanged(i, $event: PluginEditEvent) {
this.pluginObject.cardInfoArray[i][$event.field] = $event.value;
$event.value = this.pluginObject.cardInfoArray
this.valuesChanged.emit({field: "cardInfoArray", value: $event.value, type: 'parent'})
}
cardUrlValueChanged(i, j, $event: PluginEditEvent) {
if (this.editTemplate) {
this.pluginObject.cardInfoArray[i].urlsArray[j][$event.field] = $event.value;
$event.value = this.pluginObject.cardInfoArray;
} else {
this.pluginObject.cardInfoArray[i].urlsArray[j][$event.field] = $event.value;
$event.value = this.pluginObject.cardInfoArray;
}
this.valuesChanged.emit({field: "cardInfoArray", value: $event.value, type: 'parent'})
}
edit(i) {
this.selectedIndex = i;
this.toggleSubMenu(true);
}
close() {
this.selectedIndex = -1;
this.toggleSubMenu(false);
}
}

View File

@ -0,0 +1,31 @@
<div *ngIf="pluginObject" class="plugin-how-to-use uk-container uk-container-large uk-section">
<h3 class="uk-h2 uk-margin-large-bottom">
{{pluginObject.title}}
</h3>
<p *ngIf="pluginObject.description && pluginObject.description.length > 0"> {{pluginObject.description}}</p>
<div class="uk-padding" uk-height-match=".title">
<div class="uk-padding uk-grid uk-child-width-1-3@m uk-child-width-1-1 uk-grid-large" uk-grid
uk-height-match=".description">
<ng-container *ngFor="let card of pluginObject.cardInfoArray">
<ng-container *ngIf="card.show">
<div class="uk-flex uk-flex-column uk-flex-middle">
<div *ngIf="card.icon" class="uk-card uk-card-default uk-card-body">
<icon [name]="card.icon" [type]="'outlined'" [ratio]="3" [flex]="true"></icon>
</div>
<h5 class="title">
{{card.title}}
</h5>
<div class="uk-text-center uk-margin-bottom description">
{{card.description}}
</div>
<a *ngFor="let url of card.urlsArray" [href]="card.url" [class.uk-hidden]="!(url.url && url.url.length > 0)"
class="uk-display-inline-block uk-text-uppercase uk-button uk-button-text uk-text-default"
[target]="url.target" [routerLink]="url.route?url.url:null" [class.uk-disabled] =previewInAdmin>
{{url.linkText}}
</a>
</div>
</ng-container>
</ng-container>
</div>
</div>
</div>

View File

@ -0,0 +1,24 @@
import {Component} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo, PluginInfoCards, PluginURL} from "../../utils/base-plugin.component";
export class PluginCardInfo extends PluginBaseInfo{
title:string ="Lorem ipsum";
description:string = "Lorem ipsum";
cardInfoArray: PluginInfoCards[] = [
{title: "Card 1", description: "Lorem ipsum", icon:"description", urlsArray:[ new PluginURL("https://exapmle.com","View all")], show:true},
{title: "Card 2", description: "Lorem ipsum", icon:"description", urlsArray:[ new PluginURL("https://exapmle.com","")/*, new PluginURL("","Guide for the managers")*/], show:true},
{title: "Card 3", description: "Lorem ipsum", icon:"description", urlsArray:[ new PluginURL("https://exapmle.com","View all")], show:true}
];
compare(oldObject){
oldObject = super.compare(oldObject)
return oldObject;
}
}
@Component({
selector: 'plugin-card-info',
templateUrl: 'plugin-card-info.component.html'
})
export class PluginCardInfoComponent extends PluginBaseComponent<PluginCardInfo>{
constructor() {
super()
}
}

View File

@ -0,0 +1,25 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {IconsModule} from "../../../../utils/icons/icons.module";
import {NumberRoundModule} from "../../../../utils/pipes/number-round.module";
import {IconsService} from "../../../../utils/icons/icons.service";
import {SearchResearchResultsServiceModule} from "../../../../services/searchResearchResultsService.module";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {PluginCardInfoComponent} from "./plugin-card-info.component";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule, PluginFieldEditModule
],
providers:[PluginsService],
declarations: [PluginCardInfoComponent],
exports: [PluginCardInfoComponent]
})
export class PluginCardInfoModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([])
}
}

View File

@ -0,0 +1,18 @@
<div class="plugin-discover-by-subcommunity uk-container uk-container-large uk-section">
<h3 class="uk-text-center uk-margin-large-bottom">
{{pluginObject.title}}
</h3>
<ul *ngIf="subcommunities" class="uk-subnav uk-subnav-pill uk-flex uk-flex-center">
<li *ngFor="let item of subcommunities.slice(0,15)" class="uk-margin-small-bottom">
<a [routerLink]="properties.searchLinkToAdvancedResults" [queryParams]="{f0:'conceptname', fv0:item.label}" [class.uk-disabled] =previewInAdmin>
<!--{{item.category}} : {{item.subCommunityId}} - --> {{item.label}}
</a>
</li>
</ul>
<div *ngIf="subcommunities && subcommunities.length == 0" class="uk-text-muted uk-text-center">
No subcommunities available
</div>
<div *ngIf="!community && !subcommunities" class="uk-text-muted uk-text-center">
No community info available
</div>
</div>

View File

@ -0,0 +1,31 @@
import {Component} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo} from "../../utils/base-plugin.component";
import {HttpClient} from "@angular/common/http";
import {CommunityService} from "../../../../connect/community/community.service";
export class PluginDiscoverBySubcommunity extends PluginBaseInfo{
title:string ="Discover content by sub-community";
}
@Component({
selector: 'plugin-discover-by-subcommunity',
templateUrl: 'plugin-discover-by-subcommunity.component.html'
})
export class PluginDiscoverBySubcommunityComponent extends PluginBaseComponent<PluginDiscoverBySubcommunity>{
subcommunities = null;
community;
constructor(http:HttpClient, private communityService: CommunityService) {
super()
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(
community => {
this.community = community;
if(community) {
this.subscriptions.push(http.get(this.properties.communityAPI + community.communityId
+ "/subcommunities?all=false").subscribe(res => {
console.log(res)
this.subcommunities = res ? res : [] /* = res.splice(0,15)*/;
}));
}
}));
}
}

View File

@ -0,0 +1,21 @@
import {Component} from '@angular/core';
import {PluginDiscoverBySubcommunity} from "./plugin-discover-by-subcommunity.component";
import {PluginBaseFormComponent} from "../../utils/base-plugin.form.component";
@Component({
selector: 'plugin-discover-by-subcommunity-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<plugin-field-edit [value]="pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)" ></plugin-field-edit>
</div>
`,
})
export class PluginDiscoverBySubcommunityFormComponent extends PluginBaseFormComponent<PluginDiscoverBySubcommunity> {
constructor() {
super()
}
}

View File

@ -0,0 +1,25 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {IconsModule} from "../../../../utils/icons/icons.module";
import {NumberRoundModule} from "../../../../utils/pipes/number-round.module";
import {IconsService} from "../../../../utils/icons/icons.service";
import {SearchResearchResultsServiceModule} from "../../../../services/searchResearchResultsService.module";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {PluginDiscoverBySubcommunityComponent} from './plugin-discover-by-subcommunity.component';
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule, PluginFieldEditModule
],
providers:[PluginsService],
declarations: [PluginDiscoverBySubcommunityComponent],
exports: [PluginDiscoverBySubcommunityComponent]
})
export class PluginDiscoverBySubcommunityModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([])
}
}

View File

@ -0,0 +1,37 @@
<div class="plugin-featured-datasets uk-container uk-container-large uk-section">
<div class="uk-flex uk-flex-middle uk-flex-between ">
<h3 class="uk-margin-remove">
{{pluginObject.title}}
</h3>
<!-- <a [routerLink]="properties.searchLinkToAdvancedResults"
[queryParams]="{f0:'categoryid', fv0: 'enermaps::selection'}"
class="uk-display-inline-block uk-text-uppercase uk-button uk-button-text uk-text-default">
Browse all
</a>-->
</div>
<div>
<div class="uk-margin-top uk-margin-medium-bottom uk-text-meta">
<div>{{pluginObject.textLine1}}</div>
<div>
{{pluginObject.textLine2}}
</div>
</div>
<div *ngIf="results" class=" uk-card uk-card-default uk-padding-xsmall">
<div>
<paging-no-load [totalResults]="results.length" [currentPage]="page" (pageChange)="page = $event.value"
[size]="size"></paging-no-load>
</div>
<div class="uk-margin-top">
<ng-container *ngFor="let result of results.slice((page-1)*slideItems,(page)*slideItems)">
<result-preview [properties]="properties" [showOrganizations]="true"
[showSubjects]="true" [result]="result" [showEnermaps]="true"
[isCard]="true" [showEntityActions]="false" [class.uk-disabled] =previewInAdmin>
</result-preview>
</ng-container>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,71 @@
import {Component, SimpleChanges} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo} from "../../utils/base-plugin.component";
import {FetchResearchResults} from "../../../../utils/fetchEntitiesClasses/fetchResearchResults.class";
import {SearchResearchResultsService} from "../../../../services/searchResearchResults.service";
import {properties} from "../../../../../../environments/environment";
import {ResultPreview} from "../../../../utils/result-preview/result-preview";
export class PluginFeaturedDatasets extends PluginBaseInfo{
title: string = "Featured datasets";
textLine1: string = "Here are listed some of the most important energy datasets as selected by energy experts.";
textLine2: string = "Check them if you want to easily explore and visualize the European energy landscape, using only well-known datasets which you can trust.";
}
@Component({
selector: 'plugin-featured-datasets',
templateUrl: 'plugin-featured-datasets.component.html'
})
export class PluginFeaturedDatasetsComponent extends PluginBaseComponent<PluginFeaturedDatasets> {
default = new PluginFeaturedDatasets();
// public fetchFeaturedDatasets: FetchResearchResults;
page = 1;
size = 3;
slides = 1;
slideItems = 3;
totalNum = null;
results: ResultPreview[] = null;
constructor(private _searchResearchResultsService: SearchResearchResultsService) {
super()
// this.fetchFeaturedDatasets = new FetchResearchResults(this._searchResearchResultsService);
// this.fetchFeaturedDatasets.searchUtils.size = this.size;
// this.fetchFeaturedDatasets.getAllResultsForCommunity("dataset", "enermaps", 1, 50, this.properties, "enermaps::selection");
this.subscriptions.push(this._searchResearchResultsService.advancedSearchResults("dataset", null, 1, 50, null, properties, "&type=results&fq=communityid=enermaps&fq=categoryid=" + encodeURIComponent("enermaps::selection")).subscribe(
data => {
console.log(data);
this.totalNum = data[0];
this.results = data[1].map( res => {
let resultPreview = ResultPreview.searchResultConvert(res, 'dataset')
resultPreview.hostedBy_collectedFrom = null;
resultPreview.measure = null;
return resultPreview
}) ;
console.log(this.totalNum = data[0], this.results);
if(this.results && this.results.length>0) {
this.calculatePages();
}
},
err => {
}
));
}
/* ngOnChanges(changes: SimpleChanges) {
if(this.results) {
this.calculatePages();
}
}*/
calculatePages(){
this.slides = 1;
if (this.results.length > this.slideItems) {
this.slides = parseInt('' + (this.results.length / this.slideItems));
if(this.slides< (this.results.length / this.slideItems)){
this.slides++;
}
}
}
}

View File

@ -0,0 +1,37 @@
import {Component} from '@angular/core';
import {OpenaireEntities} from "../../../../utils/properties/searchFields";
import {PluginFeaturedDatasets} from "./plugin-featured-datasets.component";
import {PluginBaseFormComponent} from "../../utils/base-plugin.form.component";
@Component({
selector: 'plugin-featured-datasets-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<div class="uk-margin-bottom">
<plugin-field-edit [value]="pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)"></plugin-field-edit>
</div>
<div class="uk-margin-bottom">
<plugin-field-edit [value]="pluginObject.textLine1"
type="text" field="textLine1" (changed)="valueChanged($event)"></plugin-field-edit>
</div>
<div class="uk-margin-bottom">
<plugin-field-edit [value]="pluginObject.textLine2"
type="text" field="textLine2" (changed)="valueChanged($event)"></plugin-field-edit>
</div>
</div>
`,
})
export class PluginFeaturedDatasetsFormComponent extends PluginBaseFormComponent<PluginFeaturedDatasets> {
selectedIndex = null;
openaireEntities = OpenaireEntities;
constructor() {
super()
}
}

View File

@ -0,0 +1,29 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {IconsModule} from "../../../../utils/icons/icons.module";
import {NumberRoundModule} from "../../../../utils/pipes/number-round.module";
import {IconsService} from "../../../../utils/icons/icons.service";
import {SearchResearchResultsServiceModule} from "../../../../services/searchResearchResultsService.module";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {PluginFeaturedDatasetsComponent} from './plugin-featured-datasets.component';
import {NoLoadPaging} from "../../../../searchPages/searchUtils/no-load-paging.module";
import {SearchResultsModule} from "../../../../searchPages/searchUtils/searchResults.module";
import {ResultPreviewModule} from "../../../../utils/result-preview/result-preview.module";
import {PagingModule} from "../../../../utils/paging.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule, ResultPreviewModule, PagingModule
],
providers:[PluginsService],
declarations: [PluginFeaturedDatasetsComponent],
exports: [PluginFeaturedDatasetsComponent]
})
export class PluginFeaturedDatasetsModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([])
}
}

View File

@ -0,0 +1,229 @@
<div *ngIf="!community " class="uk-text-meta uk-text-center">
No community info available
</div>
<div class="uk-section uk-container" *ngIf="community ">
<div class="uk-grid uk-child-width-1-2@m uk-child-width-1-1@s ">
<div *ngIf="portal && community" class="">
<div *ngIf="pluginObject.showShortTitle"
class="uk-text-primary">
{{community.displayShortTitle}}
</div>
<h1 *ngIf="pluginObject.showTitle" class=" uk-h2 uk-margin-remove">
{{community.displayTitle}}
</h1>
<div *ngIf="pluginObject.description" [innerHTML]="community.description"></div>
<div *ngIf="pluginObject.searchbar && isRouteEnabled(searchLinkToResults)" [class.uk-invisible]="disableSelect"
class="uk-margin-medium-top">
<advanced-search-input #advanced (searchEmitter)="goTo(true)">
<entities-selection class="uk-width-1-3" [simpleView]="true" currentEntity="result"
[selectedEntity]="selectedEntity"
(selectionChange)="entityChanged($event);advanced.focusNext(input, $event)"
(disableSelectEmitter)="disableSelectChange($event)"
[onChangeNavigate]="false"></entities-selection>
<div input #input class="uk-width-expand" placeholder="Scholary works" [searchable]="true"
[hint]="'Search in OpenAIRE'" [(value)]="keyword"></div>
</advanced-search-input>
</div>
<div
*ngIf="(pluginObject.fos && isRouteEnabled('/fields-of-science')) || (pluginObject.sdgs && isRouteEnabled('/sdgs'))"
class="uk-padding-small uk-margin-small-top">
<div class="uk-text-meta">
Try browsing by:
</div>
<div class="link-actions uk-flex uk-flex-column uk-flex-top uk-margin-small-top">
<a *ngIf="pluginObject.sdgs && isRouteEnabled('/sdgs')" [class.uk-disabled] =previewInAdmin
class="uk-display-inline-block uk-text-uppercase uk-button uk-button-text uk-margin-small-bottom"
routerLinkActive="router-link-active" routerLink="/sdgs">
<span class="uk-flex uk-flex-middle">
<img src="assets/common-assets/sdg/sdg-dot-img.svg" alt="SDGs logo" loading="lazy" width="17px"
height="17px">
<span class="uk-margin-small-left">Sustainable Development Goals (SDG<span
class="uk-text-lowercase">s</span>)</span>
</span>
</a>
<a *ngIf="pluginObject.fos&& isRouteEnabled('/fields-of-science') " [class.uk-disabled] =previewInAdmin
class="uk-display-inline-block uk-text-uppercase uk-button uk-button-text"
routerLinkActive="router-link-active" routerLink="/fields-of-science">
<span class="uk-flex uk-flex-middle">
<img src="assets/common-assets/fos/fos-icon.svg" alt="FOS logo" loading="lazy" width="17px"
height="8px">
<span class="uk-margin-small-left">Fields of Science (FoS)</span>
</span>
</a>
</div>
</div>
</div>
<div>
<div class="heroBackground generalSearchForm uk-border-rounded uk-padding uk-margin-medium-bottom"
[class.uk-light]="!this.fontsDarkMode"
[style]="style">
<div class="plugin-content">
<div class="uk-text-lead uk-text-large uk-text-bold uk-margin-bottom">
{{ pluginObject.title}}
</div>
<ng-container *ngIf="community">
<div *ngIf="isRouteEnabled('/curators') && isVisible('curators')"
class="uk-text-small uk-margin-xsmall-bottom" [class.uk-disabled] =previewInAdmin>
<curators [longView]="false"></curators>
</div>
<div *ngIf="community.date && isVisible('date')" class="uk-text-small">
<span>Created: </span> {{community.date | date:'dd-MMM-yyyy'}}
</div>
<div class="uk-grid uk-grid-large uk-grid-stack uk-margin-top" uk-grid uk-height-match=".info-number">
<div>
<div *ngIf="projectTotal && projectTotal > 0 && isEntityEnabled('project')
&& isRouteEnabled(searchLinkToProjects) && isVisible('projects')"
class="uk-flex uk-flex-column uk-margin-bottom info-number">
<a class="uk-h5 uk-margin-remove" [queryParams]=params
routerLinkActive="router-link-active"
[routerLink]="searchLinkToProjects" [class.uk-disabled] =previewInAdmin>
{{projectTotal|number}}
</a>
<span class="uk-flex uk-flex-middle uk-text-small">
Projects
<a *ngIf="projectsCalculated && (projectTotal && projectTotal > 0 && isEntityEnabled('project') && isRouteEnabled(searchLinkToProjects))"
[title]="buildProjectsTooltip()"
[attr.uk-tooltip]="'pos: bottom-right; delay: 10;'"
class="uk-link-reset uk-margin-xsmall-left" [class.uk-disabled] =previewInAdmin>
<icon [name]="'help_outline'" [type]="'outlined'" [ratio]="0.8" [flex]="true"
[customClass]="'uk-text-meta'"></icon>
</a>
</span>
</div>
<div *ngIf="contentProviderTotal && contentProviderTotal > 0 && isEntityEnabled('datasource') &&
isRouteEnabled(searchLinkToDataProviders) && isVisible('datasources')"
class="uk-flex uk-flex-column info-number">
<a class="uk-h5 uk-margin-remove" [queryParams]=params
routerLinkActive="router-link-active"
[routerLink]="searchLinkToDataProviders" [class.uk-disabled] =previewInAdmin>
{{contentProviderTotal|number}}
</a>
<span class="uk-flex uk-flex-middle uk-text-small">
{{openaireEntities.DATASOURCES}}
<a *ngIf="contentProvidersCalculated && (contentProviderTotal && contentProviderTotal > 0 && isEntityEnabled('datasource') && isRouteEnabled(searchLinkToDataProviders))"
[title]="buildContentProvidersTooltip()"
[attr.uk-tooltip]="'pos: bottom-right; delay: 10;'"
class="uk-link-reset uk-margin-xsmall-left" [class.uk-disabled] =previewInAdmin>
<icon [name]="'help_outline'" [type]="'outlined'" [ratio]="0.8" [flex]="true"
[customClass]="'uk-text-meta'"></icon>
</a>
</span>
</div>
</div>
<div>
<div *ngIf="(zenodoCommunityIdS.length + ((masterZenodoCommunity) ? 1 : 0) > 0) && isRouteEnabled(shareInZenodoPage)
&& isVisible('communities')"
class="uk-flex uk-flex-column uk-margin-bottom info-number">
<a class="uk-h5 uk-margin-remove" [queryParams]=params
routerLinkActive="router-link-active" [routerLink]="shareInZenodoPage" [class.uk-disabled] =previewInAdmin>
{{zenodoCommunityIdS.length + ((masterZenodoCommunity) ? 1 : 0)}}
</a>
<span class="uk-flex uk-flex-middle uk-text-small">
Linked Zenodo Communities
<a [title]="buildZenodoCommunitiesTooltip()"
[attr.uk-tooltip]="'pos: bottom-right; delay: 10;'"
class="uk-link-reset uk-margin-xsmall-left" [class.uk-disabled] =previewInAdmin>
<icon [name]="'help_outline'" [type]="'outlined'" [ratio]="0.8" [flex]="true"
[customClass]="'uk-text-meta'"></icon>
</a>
</span>
</div>
<div
*ngIf="isRouteEnabled('/subjects') && displayedAllSubjects && displayedAllSubjects.length > 0 && isVisible('subjects')"
class="uk-flex uk-flex-column uk-margin-bottom info-number">
<a class="uk-h5 uk-margin-remove"
routerLinkActive="router-link-active" [routerLink]="'/subjects'" [class.uk-disabled] =previewInAdmin>
{{displayedAllSubjects.length}}
</a>
<span class="uk-text-small">
Subjects
</span>
</div>
</div>
</div>
</ng-container>
</div>
</div>
<div *ngIf="community" class="plugin2 uk-flex uk-flex-middle uk-flex-wrap" style="grid-gap: 30px;">
<div class="uk-flex uk-flex-middle" *ngIf="resultCounts && resultCounts.publications > 0 && isEntityEnabled('publication')
&& isRouteEnabled(searchLinkToResults) &&
isVisible('publications')">
<icon [name]="'description'" [type]="'outlined'" [ratio]="2" [flex]="true"
[customClass]="'uk-margin-small-right uk-text-secondary'"></icon>
<a [queryParams]="getParamsForSearchLink('publications')"
[routerLink]="properties.searchLinkToAdvancedResults" [class.uk-disabled] =previewInAdmin
class="uk-link-reset uk-flex uk-flex-column">
<span class="uk-text-xsmall">
{{openaireEntities.PUBLICATIONS}}
</span>
<span *ngIf="resultCounts" class="uk-h6 uk-margin-remove uk-button-link"
[innerHTML]="resultCounts.publications | numberRound: 1:1">
</span>
</a>
</div>
<div class="uk-flex uk-flex-middle" *ngIf="resultCounts && resultCounts.datasets > 0 && isEntityEnabled('dataset')
&& isRouteEnabled(searchLinkToResults) &&
isVisible('datasets')">
<icon [name]="'database'" [type]="'outlined'" [ratio]="2" [flex]="true"
[customClass]="'uk-margin-small-right uk-text-secondary'"></icon>
<a [queryParams]="getParamsForSearchLink('datasets')" [routerLink]="properties.searchLinkToAdvancedResults"
class="uk-link-reset uk-flex uk-flex-column" [class.uk-disabled] =previewInAdmin>
<span class="uk-text-xsmall">
{{openaireEntities.DATASETS}}
</span>
<span *ngIf="resultCounts" class="uk-h6 uk-margin-remove uk-button-link"
[innerHTML]="resultCounts.datasets | numberRound: 1:1">
</span>
</a>
</div>
<!--<div class="uk-flex uk-flex-middle" *ngIf="resultCounts && resultCounts.datasets > 0 && isEntityEnabled('dataset')
&& isRouteEnabled(searchLinkToResults) &&
isVisible('datasets')">
<icon [name]="'database'" [type]="'outlined'" [ratio]="2" [flex]="true" [customClass]="'uk-margin-small-right uk-text-secondary'"></icon>
<a [queryParams]="getParamsForSearchLink('datasets')" [routerLink]="properties.searchLinkToAdvancedResults" class="uk-link-reset uk-flex uk-flex-column">
<span class="uk-text-xsmall">
{{openaireEntities.DATASETS}}
</span>
<span *ngIf="resultCounts" class="uk-h6 uk-margin-remove uk-button-link" [innerHTML]="resultCounts.datasets | numberRound: 1:1">
</span>
</a>
</div>-->
<div class="uk-flex uk-flex-middle" *ngIf="resultCounts && resultCounts.software > 0 && isEntityEnabled('software')
&& isRouteEnabled(searchLinkToResults) &&
isVisible('software')">
<icon [name]="'integration_instructions'" [type]="'outlined'" [ratio]="2" [flex]="true"
[customClass]="'uk-margin-small-right uk-text-secondary'"></icon>
<a [queryParams]="getParamsForSearchLink('software')" [routerLink]="properties.searchLinkToAdvancedResults"
class="uk-link-reset uk-flex uk-flex-column" [class.uk-disabled] =previewInAdmin>
<span class="uk-text-xsmall">
{{openaireEntities.SOFTWARE}}
</span>
<span *ngIf="resultCounts" class="uk-h6 uk-margin-remove uk-button-link"
[innerHTML]="resultCounts.software | numberRound: 1:1">
</span>
</a>
</div>
<div class="uk-flex uk-flex-middle" *ngIf="resultCounts && resultCounts.other > 0 && isEntityEnabled('orp')
&& isRouteEnabled(searchLinkToResults) &&
isVisible('other')">
<icon [name]="'apps'" [type]="'outlined'" [ratio]="2" [flex]="true"
[customClass]="'uk-margin-small-right uk-text-secondary'"></icon>
<a [queryParams]="getParamsForSearchLink('other')" [routerLink]="properties.searchLinkToAdvancedResults"
class="uk-link-reset uk-flex uk-flex-column" [class.uk-disabled] =previewInAdmin>
<span class="uk-text-xsmall">
{{openaireEntities.OTHER}}
</span>
<span *ngIf="resultCounts" class="uk-h6 uk-margin-remove uk-button-link"
[innerHTML]="resultCounts.other | numberRound: 1:1">
</span>
</a>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,16 @@
.plugin-gateway-information {
overflow: hidden;
position: relative;
.plugin-background {
object-fit: cover;
opacity: 0.3;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.plugin-content {
position: relative;
}
}

View File

@ -0,0 +1,275 @@
import {ChangeDetectorRef, Component} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo} from "../../utils/base-plugin.component";
import {ConfigurationService} from '../../../../../openaireLibrary/utils/configuration/configuration.service';
import {CommunityService} from '../../../../../openaireLibrary/connect/community/community.service';
import {SearchCommunityProjectsService} from '../../../../../openaireLibrary/connect/projects/searchProjects.service';
import {SearchCommunityDataprovidersService} from '../../../../../openaireLibrary/connect/contentProviders/searchDataproviders.service';
import {ZenodoCommunitiesService} from '../../../../../openaireLibrary/connect/zenodoCommunities/zenodo-communities.service';
import {User} from '../../../../../openaireLibrary/login/utils/helper.class';
import {RouterHelper} from "../../../../utils/routerHelper.class";
import {OpenaireEntities} from "../../../../utils/properties/searchFields";
import {HttpClient} from "@angular/common/http";
import {Filter} from "../../../../searchPages/searchUtils/searchHelperClasses.class";
import {Router} from "@angular/router";
import {SearchResearchResultsService} from "../../../../services/searchResearchResults.service";
import {CustomizationService} from "../../../../services/customization.service";
export class PluginGatewayInformation extends PluginBaseInfo{
showTitle:boolean = true;
showShortTitle:boolean = false;
description:boolean = false;
sdgs:boolean = false;
fos:boolean = false;
searchbar:boolean = false;
title:string ="Gateway Information";
curators:boolean = true;
date:boolean = true;
communities:boolean = true;
projects:boolean = true;
organizations:boolean = true;
datasources:boolean = true;
subjects:boolean = true;
publications:boolean = true;
datasets:boolean = true;
software:boolean = true;
other:boolean = true;
compare(oldObject): any {
let newObj= super.compare(oldObject);
return newObj;
}
}
@Component({
selector: 'plugin-gateway-information',
templateUrl: 'plugin-gateway-information.component.html',
styleUrls: ['plugin-gateway-information.component.less']
})
export class PluginGatewayInformationComponent extends PluginBaseComponent<PluginGatewayInformation>{
default = new PluginGatewayInformation();
community = null;
portal = null;
params: any = {};
projectTotal = null;
contentProviderTotal = null;
projectsCalculated: boolean = false;
contentProvidersCalculated: boolean = false;
zenodoCommunityIdS = [];
masterZenodoCommunity = null;
searchLinkToProjects: string = null;
searchLinkToDataProviders: string = null;
shareInZenodoPage: string = null;
displayedAllSubjects = [];
displayedSubjects = [];
displayedSdg = [];
displayedFos = [];
resultCounts = null;
private user: User;
searchLinkToResults: string = null;
public routerHelper: RouterHelper = new RouterHelper();
openaireEntities= OpenaireEntities;
selectedEntity = 'result';
selectedEntitySimpleUrl;
selectedEntityAdvancedUrl;
resultTypes: Filter = {
values: [],
filterId: "type",
countSelectedValues: 0,
filterType: 'checkbox',
originalFilterId: "",
valueIsExact: true,
title: "Type",
filterOperator: "or"
};
keyword: string = "";
// customFilter;
placeholderText = "Search by title, author, abstract, DOI, orcid... ";
resultsQuickFilter: { filter: Filter, selected: boolean, filterId: string, value: string } = {
filter: null,
selected: true,
filterId: "resultbestaccessright",
value: "Open Access"
};
disableSelect: boolean = true;
constructor(private http:HttpClient,
private config: ConfigurationService,
private communityService: CommunityService,
private searchCommunityProjectsService: SearchCommunityProjectsService,
private searchCommunityDataprovidersService: SearchCommunityDataprovidersService,
private zenodoCommunitiesService: ZenodoCommunitiesService, private _router: Router,
private _searchResearchResultsService: SearchResearchResultsService,
private cdr: ChangeDetectorRef, protected layoutService: CustomizationService) {
super();
this.searchLinkToResults = this.properties.searchLinkToResults;
this.searchLinkToProjects = this.properties.searchLinkToProjects;
this.searchLinkToDataProviders = this.properties.searchLinkToDataProviders;
this.shareInZenodoPage = this.properties.shareInZenodoPage;
this.subscriptions.push(this.config.portalAsObservable.subscribe(
res => {
this.portal = res;
},
error => {
console.log(error);
}
));
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(
community => {
this.community = community;
if (community) {
this.displayedSubjects = community.subjects;
this.displayedSdg = community.sdg;
this.displayedFos = community.fos;
this.displayedSubjects.forEach(element => {
this.displayedAllSubjects.push({value: element, type: 'resultsubject'});
});
this.displayedSdg.forEach(element => {
this.displayedAllSubjects.push({value: element, type: 'sdg'});
});
this.displayedFos.forEach(element => {
this.displayedAllSubjects.push({value: element, type: 'fos'});
});
if (this.properties.environment == "development") {
this.params = {communityId: community.communityId};
}
if (this.community.zenodoCommunity) {
this.subscriptions.push(this.zenodoCommunitiesService.getZenodoCommunityById(this.properties, this.community.zenodoCommunity).subscribe(
res => {
this.masterZenodoCommunity = res;
},
error => {
console.log(error);
}
));
}
this.zenodoCommunityIdS = this.community.otherZenodoCommunities;
// Double check below: is `this.community.communityId` correct? the other way was through @input communityID from ConnectHelper service - domain
this.subscriptions.push(this.searchCommunityProjectsService.countTotalProjects(this.properties, this.community.communityId).subscribe(
res => {
this.projectTotal = res;
},
error => {
console.log(error);
},
() => {
this.projectsCalculated = true;
}
));
// Double check below: is `this.community.communityId` correct? the other way was through @input communityID from ConnectHelper service - domain
this.subscriptions.push(this.searchCommunityDataprovidersService.countTotalDataproviders(this.properties, this.community.communityId).subscribe(
res => {
this.contentProviderTotal = res;
},
error => {
console.log(error);
},
() => {
this.contentProvidersCalculated = true;
}
));
this.subscriptions.push(this._searchResearchResultsService.countResults("communityid", this.community.communityId).subscribe(res => {
this.resultCounts = res;
}));
}
}
));
}
ngOnInit() {
if (this.community) {
this.getLayout(this.community.communityId);
}
}
isEntityEnabled(entity: string) {
return this.portal.entities.some(x => x['pid'] == entity && x['isEnabled'] === true);
}
isRouteEnabled(route: string) {
return this.portal && this.portal.pages.some(x => x['route'] == route && x['isEnabled'] === true);
}
buildProjectsTooltip(): string {
let tooltipContent: string = "<div>";
if (this.projectTotal != null && this.projectTotal > 0 && this.isEntityEnabled('project') && this.isRouteEnabled(this.searchLinkToProjects)) {
tooltipContent += "<span class='uk-text-bold'>Projects</span>";
}
tooltipContent += " have been selected as relevant for your community by the gateway curators.";
tooltipContent += "</div>";
return tooltipContent;
}
public buildContentProvidersTooltip(): string {
let tooltipContent: string = "<div>";
if (this.contentProviderTotal != null && this.contentProviderTotal > 0 && this.isEntityEnabled('datasource') && this.isRouteEnabled(this.searchLinkToDataProviders)) {
tooltipContent += "<span class='uk-text-bold'>Data sources</span>";
}
tooltipContent += " have been selected as relevant for your community by the gateway curators.";
tooltipContent += "</div>";
return tooltipContent;
}
public buildZenodoCommunitiesTooltip(): string {
let tooltipContent: string = "<div>";
tooltipContent += "<span class='uk-text-bold'>Zenodo</span> is a catch-all repository for OpenAIRE.";
tooltipContent += "<div class='uk-margin-small-top'>A <span class='uk-text-bold'>Zenodo Community</span> is created and curated by Zenodo users.</div>";
tooltipContent += "</div>";
return tooltipContent;
}
public getParamsForSearchLink(type: string = "") {
if (type) {
return this.routerHelper.createQueryParams(['type', 'qf', 'sortBy'], [type, 'false', 'resultdateofacceptance,descending']);
} else {
return {};
}
}
entityChanged($event) {
this.selectedEntity = $event.entity;
this.selectedEntitySimpleUrl = $event.simpleUrl;
this.selectedEntityAdvancedUrl = $event.advancedUrl;
if (this.selectedEntity == 'result') {
this.placeholderText = "Search by title, author, abstract, DOI, orcid... ";
} else if (this.selectedEntity == 'project') {
this.placeholderText = "Search by project title, grant id, funder...";
} else if (this.selectedEntity == 'dataprovider') {
this.placeholderText = "Search by name...";
} else {
this.placeholderText = "Search community content";
}
}
goTo(simple: boolean) {
let url = (simple) ? this.selectedEntitySimpleUrl : this.selectedEntityAdvancedUrl;
let parameterNames = [];
let parameterValues = [];
if (this.keyword.length > 0) {
parameterNames.push("fv0");
parameterValues.push(this.keyword);
parameterNames.push("f0");
parameterValues.push("q");
}
this._router.navigate([url], {queryParams: this.routerHelper.createQueryParams(parameterNames, parameterValues)});
}
disableSelectChange(event: boolean) {
this.disableSelect = event;
this.cdr.detectChanges();
}
}

View File

@ -0,0 +1,168 @@
import {Component} from '@angular/core';
import {PluginGatewayInformation} from "./plugin-gateway-information.component";
import {OpenaireEntities} from "../../../../utils/properties/searchFields";
import {PluginBaseFormComponent} from "../../utils/base-plugin.form.component";
@Component({
selector: 'plugin-gateway-information-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<plugin-field-edit [value]="pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)"></plugin-field-edit>
<div class="uk-margin-top uk-text-meta uk-text-small uk-margin-small-bottom">
Show or hide the following information:
</div>
<div class="uk-margin-top uk-text-meta uk-text-xsmall ">
Community info
</div>
<div class="uk-grid uk-child-width-1-1 uk-text-small uk-hr ">
<div class="uk-margin-xsmall-bottom uk-margin-xsmall-top">
<plugin-field-edit [value]=" pluginObject.showTitle"
type="checkbox" field="showTitle" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit> Title
</div>
<div class="uk-margin-xsmall-bottom uk-margin-xsmall-top">
<plugin-field-edit [value]=" pluginObject.showShortTitle"
type="checkbox" field="showShortTitle" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit> Short title
</div>
<div class="uk-margin-xsmall-bottom uk-margin-xsmall-top">
<plugin-field-edit [value]=" pluginObject.description"
type="checkbox" field="description" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit> Description
</div>
<div class="uk-margin-xsmall-bottom uk-margin-xsmall-top">
<plugin-field-edit [value]=" pluginObject.curators"
type="checkbox" field="curators" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>Curated by
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.date"
type="checkbox" field="date" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit> Created
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.projects"
type="checkbox" field="projects" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
{{openaireEntities.PROJECTS}}
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.communities"
type="checkbox" field="communities" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
Linked Zenodo communities
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.datasources"
type="checkbox" field="datasources" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
{{openaireEntities.DATASOURCES}}
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.subjects"
type="checkbox" field="subjects" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
Subjects
</div>
<div class="uk-alert uk-alert-warning uk-text-small uk-padding-xsmall uk-margin-medium-left "> Manage community info <a routerLink="../../info/profile" target="_blank">here</a>.</div>
<div class="uk-margin-top uk-text-meta uk-text-xsmall">
Pages & menus
</div>
<div class="uk-margin-xsmall-bottom uk-hr uk-margin-xsmall-top">
<plugin-field-edit [value]=" pluginObject.searchbar"
type="checkbox" field="searchbar" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
Search bar
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.fos"
type="checkbox" field="fos" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
Browse by FOS
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.sdgs"
type="checkbox" field="sdgs" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
Browse by SDGs
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.publications"
type="checkbox" field="publications" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
{{openaireEntities.PUBLICATIONS}}
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.datasets"
type="checkbox" field="datasets" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
{{openaireEntities.DATASETS}}
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.software"
type="checkbox" field="software" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
{{openaireEntities.SOFTWARE}}
</div>
<div class="uk-margin-xsmall-bottom">
<plugin-field-edit [value]=" pluginObject.other"
type="checkbox" field="other" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>
{{openaireEntities.OTHER}}
</div>
</div>
<div class="uk-alert uk-alert-warning uk-text-small uk-padding-xsmall"> If some information is enabled here,
but still not visible, please check related <a routerLink="../entities" target="_blank">entity</a> or <a routerLink="../pages" target="_blank">page</a>.
</div>
<div class="uk-alert uk-alert-warning uk-text-small uk-padding-xsmall">
Change the custom section background options <a routerLink="../../customize-layout" target="_blank"> here.</a>
</div>
</div>
`,
})
export class PluginGatewayInformationFormComponent extends PluginBaseFormComponent<PluginGatewayInformation> {
openaireEntities= OpenaireEntities;
constructor() {
super()
}
}

View File

@ -0,0 +1,37 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {IconsModule} from "../../../../utils/icons/icons.module";
import {NumberRoundModule} from "../../../../utils/pipes/number-round.module";
import {IconsService} from "../../../../utils/icons/icons.service";
import {SearchResearchResultsServiceModule} from "../../../../services/searchResearchResultsService.module";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {PluginGatewayInformationComponent} from './plugin-gateway-information.component';
import {CuratorsModule} from '../../../../connect/components/curators/curators.module';
import {SearchCommunityProjectsService} from '../../../../../openaireLibrary/connect/projects/searchProjects.service';
import {SearchCommunityDataprovidersService} from '../../../../../openaireLibrary/connect/contentProviders/searchDataproviders.service';
import {ZenodoCommunitiesService} from '../../../../../openaireLibrary/connect/zenodoCommunities/zenodo-communities.service';
import {AdvancedSearchInputModule} from "../../../../sharedComponents/advanced-search-input/advanced-search-input.module";
import {EntitiesSelectionModule} from "../../../../searchPages/searchUtils/entitiesSelection.module";
import {QuickSelectionsModule} from "../../../../searchPages/searchUtils/quick-selections.module";
import {InputModule} from "../../../../sharedComponents/input/input.module";
import {CustomizationServiceModule} from "../../../../services/customizationService.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule, PluginFieldEditModule,
CuratorsModule, AdvancedSearchInputModule, EntitiesSelectionModule, QuickSelectionsModule, InputModule, CustomizationServiceModule
],
providers: [
PluginsService, SearchCommunityProjectsService, SearchCommunityDataprovidersService, ZenodoCommunitiesService
],
declarations: [PluginGatewayInformationComponent],
exports: [PluginGatewayInformationComponent]
})
export class PluginGatewayInformationModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([])
}
}

View File

@ -0,0 +1,28 @@
import {Component} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo, PluginURL} from "../../utils/base-plugin.component";
export class HTMLSection extends PluginBaseInfo{
title:string ="Lorem ipsum"
html:string = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`;
fullWidth:boolean = true;
compare(oldObject): any {
let newObj= super.compare(oldObject);
return newObj;
}
}
@Component({
selector: 'plugin-html-section',
template: `
<div [class]="pluginObject.fullWidth?'':'uk-container uk-container-large'">
<h2>{{pluginObject.title}}</h2>
<div [innerHTML]="pluginObject.html">
</div>
</div>
`
})
export class PluginHtmlSectionComponent extends PluginBaseComponent<HTMLSection>{
constructor() {
super();
}
}

View File

@ -0,0 +1,33 @@
import {Component} from '@angular/core';
import {PluginBaseFormComponent, PluginEditEvent} from "../../utils/base-plugin.form.component";
import {HTMLSection} from "./plugin-html-section.component";
@Component({
selector: 'plugin-html-section-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<plugin-field-edit [value]="pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)"></plugin-field-edit>
<div class="uk-margin-top">
<plugin-field-edit [value]="pluginObject.html" [switchToHTMLEditor]="true"
type="textarea" field="html" (changed)="valueChanged($event)"></plugin-field-edit>
</div>
<div class="uk-margin-xsmall-bottom uk-margin-xsmall-top">
<plugin-field-edit [value]=" pluginObject.fullWidth"
type="checkbox" field="fullWidth" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit>Full width
</div>
</div>
`,
})
export class PluginHtmlSectionFormComponent extends PluginBaseFormComponent<HTMLSection> {
constructor() {
super()
}
}

View File

@ -0,0 +1,22 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {InputModule} from "../../../../sharedComponents/input/input.module";
import {PluginHtmlSectionComponent} from "./plugin-html-section.component";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, PluginFieldEditModule, InputModule
],
providers: [
PluginsService
],
declarations: [PluginHtmlSectionComponent],
exports: [PluginHtmlSectionComponent]
})
export class PluginHtmlSectionModule {
}

View File

@ -0,0 +1,97 @@
import {Component, SimpleChanges} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo} from "../../utils/base-plugin.component";
import {HttpClient} from "@angular/common/http";
export class PluginOpenAIREProducts extends PluginBaseInfo{
title:string ="OpenAIRE services for your community";
serviceIdsArray = ["argos","zenodo","amnesia"];
compare(oldObject): any {
return super.compare(oldObject);
}
}
@Component({
selector: 'plugin-openaire-products',
template: `
<div *ngIf="pluginObject " class="uk-container uk-section">
<h3>{{pluginObject.title}} </h3>
<div *ngIf="services && servicesToShow" uk-slider class="uk-slider">
<ul *ngIf="slides" class="uk-slider-items" uk-height-match="target: .uk-card; row: false">
<li *ngFor="let slide of [].constructor(slides); let i=index" class="uk-width-1-1 uk-padding">
<div class="uk-grid uk-child-width-1-3@m uk-child-width-1-1" uk-grid uk-scrollspy="target: [uk-scrollspy-class]; cls: uk-animation-fade; repeat: true">
<div *ngFor="let service of servicesToShow.slice((i)*slideItems,(i+1)*slideItems)" uk-scrollspy-class>
<div class="uk-card uk-card-default ">
<div class="uk-card-media-top">
<img [src]="service.logo" width="100%" height="" alt="" class="uk-height-max-small">
</div>
<div class=" uk-height-max-large uk-padding-small">
<div class="uk-text-primary">{{service.name}}</div>
<div class="uk-h5 uk-margin-remove-vertical">{{service.tagline}}</div>
<div [innerHTML]="service.description" class="uk-text-truncate uk-text-small uk-text-meta"></div>
<a class="uk-link-text" [href]="service.webpage" target="_blank">Read more</a>
</div>
</div>
</div>
</div>
</li>
</ul>
<ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin-medium-top"></ul>
</div>
<div *ngIf="showErrorMessage" class="uk-text-muted uk-text-center">
No products info available
</div>
</div>
`,
})
export class PluginOpenaireProductsComponent extends PluginBaseComponent<PluginOpenAIREProducts>{
services = null;
excludedServiceIds = ["openaire_login","research_community_dashboard"]
servicesToShow = null;
slides = 1;
slideItems = 3;
api= "https://catalogue.openaire.eu/api/catalogue-resources?from=0&quantity=100&order=asc&orderField=name";
showErrorMessage = false;
constructor(private http:HttpClient) {
super()
}
ngOnInit(): void {
super.ngOnInit();
if(!this.services) {
this.subscriptions.push(this.http.get( this.properties.cacheUrl + encodeURIComponent(this.api)).subscribe(res =>{
this.services = res["results"].map( x=> {
if(x.id.indexOf("openaire.")!=-1){
x.id = x.id.split("openaire.")[1]
}
return x;
});
this.services = this.services.filter(x=> this.excludedServiceIds.indexOf(x.id) ==-1);
this.calculatePages();
}, error => {
this.showErrorMessage = true;
}))
}else{
this.calculatePages();
}
}
ngOnChanges(changes: SimpleChanges) {
if(this.services) {
this.calculatePages();
}
}
calculatePages(){
this.slides = 1;
this.servicesToShow = this.services.filter(x => this.pluginObject.serviceIdsArray.indexOf(x.id) != -1);
if (this.servicesToShow.length > this.slideItems) {
this.slides = parseInt('' + (this.servicesToShow.length / this.slideItems));
if(this.slides< (this.servicesToShow.length / this.slideItems)){
this.slides++;
}
}
}
}

View File

@ -0,0 +1,70 @@
import {Component} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {PluginOpenAIREProducts} from "./plugin-openaire-products.component";
import {PluginBaseFormComponent, PluginEditEvent} from "../../utils/base-plugin.form.component";
@Component({
selector: 'plugin-openaire-products-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<plugin-field-edit [value]="pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)" ></plugin-field-edit>
<div class="uk-margin-medium-top uk-text-muted">
Select services:
</div>
<ng-container *ngFor="let service of services">
<div class=" uk-margin-xsmall-top">
<plugin-field-edit [value]="pluginObject.serviceIdsArray.indexOf(service.id)!=-1"
type="checkbox" field="sdgs" (editClicked)="pluginEditEvent = $event"
(changed)="serviceChanged(service.id,$event)">
</plugin-field-edit>
{{service.name}}
</div>
</ng-container>
<div *ngIf="showErrorMessage" class="uk-text-muted uk-text-center">
No products info available
</div>
</div>
`,
})
//TODO make it extend PluginOpenaireProductsComponent (to avoid call in constructor..)
export class PluginOpenaireProductsFormComponent extends PluginBaseFormComponent<PluginOpenAIREProducts>{
default = new PluginOpenAIREProducts();
services = [];
excludedServiceIds = ["openaire_login","research_community_dashboard"]
api= "https://catalogue.openaire.eu/api/catalogue-resources?from=0&quantity=100&order=asc&orderField=name";
showErrorMessage = false;
constructor(http:HttpClient) {
super()
this.subscriptions.push(http.get( this.properties.cacheUrl + encodeURIComponent(this.api)).subscribe(res =>{
this.services = res["results"].map( x=> {
x.id = x.id.split("openaire.")[1]
return x;
});
this.services = this.services.filter(x=> this.excludedServiceIds.indexOf(x.id) ==-1);
}, error => {
this.showErrorMessage = true;
}))
}
serviceChanged(id,$event:PluginEditEvent){
let index = this.pluginObject.serviceIdsArray.indexOf(id);
if(index !=-1){
this.pluginObject.serviceIdsArray.splice(index,1);
}else{
this.pluginObject.serviceIdsArray.push(id);
}
$event.value =this.pluginObject.serviceIdsArray;
this.valuesChanged.emit({field:$event.field, value: $event.value, type: 'parent'})
}
}

View File

@ -0,0 +1,25 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {IconsModule} from "../../../../utils/icons/icons.module";
import {NumberRoundModule} from "../../../../utils/pipes/number-round.module";
import {IconsService} from "../../../../utils/icons/icons.service";
import {SearchResearchResultsServiceModule} from "../../../../services/searchResearchResultsService.module";
import {PluginOpenaireProductsComponent} from "./plugin-openaire-products.component";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule, PluginFieldEditModule
],
providers:[PluginsService],
declarations: [PluginOpenaireProductsComponent],
exports: [PluginOpenaireProductsComponent]
})
export class PluginOpenaireProductsModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([])
}
}

View File

@ -0,0 +1,7 @@
<div *ngIf=" portal && isRouteEnabled('/organizations')" class="plugin-featured-datasets uk-container uk-container-large uk-section">
<affiliations [longView]="false" [getAffiliationsFromAPI]="true" [communityFirstPage]="true" [class.uk-disabled] =previewInAdmin></affiliations>
</div>
<div *ngIf="!portal " class="uk-text-muted uk-text-center">
No community info available
</div>

View File

@ -0,0 +1,34 @@
import {Component} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo} from "../../utils/base-plugin.component";
import {ConfigurationService} from "../../../../utils/configuration/configuration.service";
export class PluginOrganizations extends PluginBaseInfo{
title: string = "Supporting Organizations";
}
@Component({
selector: 'plugin-organizations',
templateUrl: 'plugin-organizations.component.html'
})
export class PluginOrganizationsComponent extends PluginBaseComponent<PluginOrganizations> {
portal;
constructor(private config: ConfigurationService) {
super()
this.subscriptions.push(this.config.portalAsObservable.subscribe(
res => {
this.portal = res;
},
error => {
console.log(error);
}
));
}
isRouteEnabled(route: string) {
return this.portal && this.portal.pages.some(x => x['route'] == route && x['isEnabled'] === true);
}
}

View File

@ -0,0 +1,24 @@
import {Component} from '@angular/core';
import {PluginOrganizations} from "./plugin-organizations.component";
import {PluginBaseFormComponent} from "../../utils/base-plugin.form.component";
@Component({
selector: 'plugin-organizations-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<plugin-field-edit [value]="pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)"></plugin-field-edit>
<div class="uk-alert uk-alert-warning uk-text-small"> Manage community organizations <a routerLink="../../info/organizations" target="_blank">here</a>.</div>
</div>
`,
})
export class PluginOrganizationsFormComponent extends PluginBaseFormComponent<PluginOrganizations> {
constructor() {
super()
}
}

View File

@ -0,0 +1,22 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {IconsService} from "../../../../utils/icons/icons.service";
import {PluginOrganizationsComponent} from './plugin-organizations.component';
import {AffiliationsModule} from "../../../../connect/affiliations/affiliations.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, AffiliationsModule,
],
providers:[PluginsService],
declarations: [PluginOrganizationsComponent],
exports: [PluginOrganizationsComponent]
})
export class PluginOrganizationsModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([])
}
}

View File

@ -0,0 +1,34 @@
<div class="uk-background-muted">
<div class="uk-position-relative">
<div class="uk-section uk-section-large">
<div class="uk-container">
<div class="uk-grid uk-child-width-1-2@m" uk-grid>
<div>
<div style="max-width: 550px;">
<h2>{{pluginObject.title}}</h2>
<div class="" [innerHTML]="pluginObject.paragraph1">
</div>
</div>
</div>
<div></div>
<img class="uk-visible@m uk-height-1-1 uk-position-top-right"
[src]="pluginObject.image" alt="Graph nodes" loading="lazy">
</div>
</div>
</div>
</div>
<div class="uk-section uk-padding-remove-top">
<div class="uk-container">
<div class="uk-width-1-2@m uk-margin-auto uk-margin-small-top uk-text-center" style="max-width: 600px;">
<div [innerHTML]="pluginObject.paragraph2"></div>
<div class="uk-margin-top">
<a [href]="pluginObject.url.url" [target]="pluginObject.url.target"
class="uk-display-inline-block uk-text-uppercase uk-button uk-button-text">
{{pluginObject.url.linkText}}
</a>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,24 @@
import {Component} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo, PluginURL} from "../../utils/base-plugin.component";
export class ParagraphInfo extends PluginBaseInfo{
title:string ="Lorem ipsum"
paragraph1:string = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`;
paragraph2:string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
url:PluginURL= new PluginURL("https://example.com","Lorem ipsum")
image:string = "https://admin.connect.openaire.eu/assets/common-assets/placeholder.png"
compare(oldObject): any {
let newObj= super.compare(oldObject);
return newObj;
}
}
@Component({
selector: 'plugin-graph-info',
templateUrl: 'plugin-graph-info.component.html'
})
export class PluginGraphInfoComponent extends PluginBaseComponent<ParagraphInfo>{
constructor() {
super();
}
}

View File

@ -0,0 +1,52 @@
import {Component} from '@angular/core';
import {PluginBaseFormComponent, PluginEditEvent} from "../../utils/base-plugin.form.component";
import {ParagraphInfo} from "./plugin-graph-info.component";
@Component({
selector: 'plugin-graph-info-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<plugin-field-edit [value]="pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)"></plugin-field-edit>
<div *ngIf="pluginTemplate.custom" class="uk-margin-top">
<plugin-field-edit [value]="pluginObject.image"
type="text" field="image" (changed)="valueChanged($event)"></plugin-field-edit>
</div>
<div class="uk-margin-top">
<plugin-field-edit [value]="pluginObject.paragraph1" [switchToHTMLEditor]="true"
type="textarea" field="paragraph1" (changed)="valueChanged($event)"></plugin-field-edit>
</div>
<div class="uk-margin-top">
<plugin-field-edit [value]="pluginObject.paragraph2" class="uk-margin-xsmall-top" [switchToHTMLEditor]="true"
type="textarea" field="paragraph2" (changed)="valueChanged($event)"></plugin-field-edit>
</div>
<div class=" uk-margin-top uk-text-meta uk-text-xsmall"> Link</div>
<div class="uk-margin-small-top">
<plugin-field-edit [value]=" pluginObject.url.url"
type="text" field="url"
(changed)="urlValueChanged($event)"></plugin-field-edit>
</div>
<div class="uk-margin-top">
<plugin-field-edit [value]=" pluginObject.url.linkText"
type="text" field="linkText" placeholder="Link text"
(changed)="urlValueChanged($event)"></plugin-field-edit>
</div>
</div>
`,
})
export class PluginGraphInfoFormComponent extends PluginBaseFormComponent<ParagraphInfo> {
constructor() {
super()
}
urlValueChanged($event: PluginEditEvent) {
this.pluginObject.url[$event.field] = $event.value;
$event.value = this.pluginObject.url;
this.valuesChanged.emit({field: "url", value: $event.value, type: 'parent'})
}
}

View File

@ -0,0 +1,22 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {InputModule} from "../../../../sharedComponents/input/input.module";
import {PluginGraphInfoComponent} from "./plugin-graph-info.component";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, PluginFieldEditModule, InputModule
],
providers: [
PluginsService
],
declarations: [PluginGraphInfoComponent],
exports: [PluginGraphInfoComponent]
})
export class PluginGraphInfoModule {
}

View File

@ -0,0 +1,137 @@
import {ChangeDetectorRef, Component} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo} from "../../utils/base-plugin.component";
import {OpenaireEntities} from "../../../../utils/properties/searchFields";
import {CustomizationService} from "../../../../services/customization.service";
import {CommunityService} from "../../../../connect/community/community.service";
import {Filter} from "../../../../searchPages/searchUtils/searchHelperClasses.class";
import {Router} from "@angular/router";
import {RouterHelper} from "../../../../utils/routerHelper.class";
export class PluginSearchBar extends PluginBaseInfo{
alternativeTitle:string ="";
showTitle:boolean = true;
showShortTitle:boolean = false;
compare(oldObject): any {
let newObj= super.compare(oldObject);
return newObj;
}
}
@Component({
selector: 'plugin-search-bar',
template: `
<div *ngIf="!community " class="uk-text-meta uk-text-center">
No community info available
</div>
<div *ngIf="community " class="generalSearchForm heroBackground" [class.uk-light]="!this.fontsDarkMode" [style]="style">
<div class="uk-container uk-container-large uk-flex uk-flex-center">
<div class="uk-width-2-3@m uk-width-1-2@l uk-margin-large-top uk-margin-large-bottom">
<h1 *ngIf="pluginObject.showShortTitle" class="uk-text-center uk-h2 uk-margin-remove">
{{community.displayShortTitle}}
</h1>
<h1 *ngIf="pluginObject.alternativeTitle.length > 0"
class="uk-text-center uk-h2 uk-margin-remove">
{{pluginObject.alternativeTitle}}
</h1>
<div *ngIf="pluginObject.showTitle"
class="uk-text-center uk-margin-top">
{{community.displayTitle}}
</div>
<div [class.uk-invisible]="disableSelect" class="uk-margin-medium-top">
<advanced-search-input #advanced (searchEmitter)="goTo(true)">
<entities-selection class="uk-width-1-3" [simpleView]="true" currentEntity="result" [selectedEntity]="selectedEntity"
(selectionChange)="entityChanged($event);advanced.focusNext(input, $event)" (disableSelectEmitter)="disableSelectChange($event)"
[onChangeNavigate]="false"></entities-selection>
<div input #input class="uk-width-expand" placeholder="Scholary works" [searchable]="true" [hint]="'Search in OpenAIRE'" [(value)]="keyword"></div>
</advanced-search-input>
</div>
</div>
</div>
</div>
`
})
export class PluginSearchBarComponent extends PluginBaseComponent<PluginSearchBar>{
disableSelect: boolean = true;
openaireEntities= OpenaireEntities;
selectedEntity = 'result';
selectedEntitySimpleUrl;
selectedEntityAdvancedUrl;
keyword: string = "";
// customFilter;
placeholderText = "Search by title, author, abstract, DOI, orcid... ";
resultTypes: Filter = {
values: [],
filterId: "type",
countSelectedValues: 0,
filterType: 'checkbox',
originalFilterId: "",
valueIsExact: true,
title: "Type",
filterOperator: "or"
};
community = null;
public routerHelper: RouterHelper = new RouterHelper();
constructor(private communityService: CommunityService, protected layoutService: CustomizationService, private cdr: ChangeDetectorRef, private _router: Router,) {
super()
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(
community => {
this.community = community;
if(community) {
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(
community => {
this.getLayout(community.communityId);
}));
}
}
));
}
ngOnInit() {
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(
community => {
if(community) {
this.getLayout(community.communityId);
}
}));
}
goTo(simple: boolean) {
let url = (simple) ? this.selectedEntitySimpleUrl : this.selectedEntityAdvancedUrl;
let parameterNames = [];
let parameterValues = [];
if (this.keyword.length > 0) {
parameterNames.push("fv0");
parameterValues.push(this.keyword);
parameterNames.push("f0");
parameterValues.push("q");
}
this._router.navigate([url], {queryParams: this.routerHelper.createQueryParams(parameterNames, parameterValues)});
}
disableSelectChange(event: boolean) {
this.disableSelect = event;
this.cdr.detectChanges();
}
entityChanged($event) {
this.selectedEntity = $event.entity;
this.selectedEntitySimpleUrl = $event.simpleUrl;
this.selectedEntityAdvancedUrl = $event.advancedUrl;
if (this.selectedEntity == 'result') {
this.placeholderText = "Search by title, author, abstract, DOI, orcid... ";
} else if (this.selectedEntity == 'project') {
this.placeholderText = "Search by project title, grant id, funder...";
} else if (this.selectedEntity == 'dataprovider') {
this.placeholderText = "Search by name...";
} else {
this.placeholderText = "Search community content";
}
}
}

View File

@ -0,0 +1,47 @@
import {Component} from '@angular/core';
import {OpenaireEntities} from "../../../../utils/properties/searchFields";
import {PluginBaseFormComponent} from "../../utils/base-plugin.form.component";
import {PluginSearchBar} from "./plugin-search-bar.component";
@Component({
selector: 'plugin-search-bar-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<plugin-field-edit [value]="pluginObject.alternativeTitle"
type="text" field="alternativeTitle" placeholder="Alternative title" (changed)="valueChanged($event)"></plugin-field-edit>
<div class="uk-margin-top uk-text-meta uk-text-small uk-margin-small-bottom">
Show or hide the following information:
</div>
<div class="uk-grid uk-child-width-1-1 uk-text-small uk-hr ">
<div class="uk-margin-xsmall-bottom uk-margin-xsmall-top">
<plugin-field-edit [value]=" pluginObject.showTitle"
type="checkbox" field="showTitle" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit> Title
</div>
<div class="uk-margin-xsmall-bottom uk-margin-xsmall-top">
<plugin-field-edit [value]=" pluginObject.showShortTitle"
type="checkbox" field="showShortTitle" (editClicked)="pluginEditEvent = $event"
(changed)="valueChanged($event)">
</plugin-field-edit> Short title
</div>
<div class="uk-alert uk-alert-warning uk-text-small uk-padding-xsmall uk-margin-medium-left "> Manage community info <a routerLink="../../info/profile" target="_blank">here</a>.</div>
</div>
</div>
`,
})
export class PluginSearchBarFormComponent extends PluginBaseFormComponent<PluginSearchBar> {
openaireEntities= OpenaireEntities;
constructor() {
super()
}
}

View File

@ -0,0 +1,30 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {IconsModule} from "../../../../utils/icons/icons.module";
import {NumberRoundModule} from "../../../../utils/pipes/number-round.module";
import {SearchResearchResultsServiceModule} from "../../../../services/searchResearchResultsService.module";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {CuratorsModule} from '../../../../connect/components/curators/curators.module';
import {AdvancedSearchInputModule} from "../../../../sharedComponents/advanced-search-input/advanced-search-input.module";
import {EntitiesSelectionModule} from "../../../../searchPages/searchUtils/entitiesSelection.module";
import {QuickSelectionsModule} from "../../../../searchPages/searchUtils/quick-selections.module";
import {InputModule} from "../../../../sharedComponents/input/input.module";
import {PluginSearchBarComponent} from "./plugin-search-bar.component";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule, PluginFieldEditModule,
CuratorsModule, AdvancedSearchInputModule, EntitiesSelectionModule, QuickSelectionsModule, InputModule,
],
providers: [
PluginsService
],
declarations: [PluginSearchBarComponent],
exports: [PluginSearchBarComponent]
})
export class PluginSearchBarModule {
}

View File

@ -0,0 +1,41 @@
<div *ngIf="pluginObject" #parent class="heroBackground generalSearchForm " [class.uk-light]="!this.fontsDarkMode"
[style]="style">
<div class="uk-section uk-container ">
<div class="uk-width-1-1 uk-margin-medium-bottom">
<h2 class="uk-margin-remove-top uk-text-center ">
{{pluginObject.title}}<span class="uk-text-primary">.</span>
</h2>
</div>
<slider-container [total]="activeCards.length" [navigation]="'progress'" [period]="6000" [infinite]="true" [parent]="parent">
<ng-container *ngIf="activeCards.length > 0">
<slider-column type="nav" class="slider-nav" style="min-height: 300px">
<ng-container *ngFor="let card of activeCards; let i = index">
<slider-nav-item [start]="i">
<div class="uk-text-primary">{{card.tag}}</div>
<div class="uk-margin-remove uk-text-large uk-text-bold">
{{card.title}}
</div>
<div class="uk-text-small">{{card.description}}</div>
<a *ngFor="let url of card.urlsArray" [route]="url.url" class="uk-display-inline-block uk-text-uppercase uk-button uk-button-text uk-text-default" [target]="url.target"
[class.uk-hidden]="!(url.url && url.url.length > 0)" [routerLink]="url.route?url.url:null" [class.uk-disabled] =previewInAdmin>
{{url.linkText}}
</a>
</slider-nav-item>
</ng-container>
</slider-column>
<slider-column type="slider">
<slider-item type="static">
<img class="uk-position-center uk-position-z-index" [src]="'https://' + (properties.environment == 'production'?'':'beta.')
+ 'connect.openaire.eu/assets/connect-assets/home/tablet.png'"
alt="ipad" loading="lazy">
</slider-item>
<ng-container *ngFor="let card of activeCards; let i = index">
<slider-item type="slide" [start]="i">
<img [src]="card.image" [alt]="card.tag" loading="lazy">
</slider-item>
</ng-container>
</slider-column>
</ng-container>
</slider-container>
</div>
</div>

View File

@ -0,0 +1,7 @@
//slider-column slider-nav-item .uk-active{
// border-left: solid 2px @primary-color;
//}
@slider-nav-item-background-active: white;
@slider-nav-item-action-background: rgba(255, 255, 255, 0.50);

View File

@ -0,0 +1,53 @@
import {Component} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo, PluginInfoCards, PluginURL} from "../../utils/base-plugin.component";
import {OpenaireEntities} from "../../../../utils/properties/searchFields";
import {properties} from "../../../../../../environments/environment";
import {CustomizationService} from "../../../../services/customization.service";
import {CommunityService} from "../../../../connect/community/community.service";
export class PluginSearchDepositLink extends PluginBaseInfo{
title:string ="Search, link and deposit your research in one place";
cardInfoArray: PluginInfoCards[] = [
{tag: "SEARCH & BROWSE", title: "Discover research products in your community.", description:
"A view of the OpenAIRE Graph, configured by experts of your research community, who want to help you out with the data and literature deluge.",
urlsArray:[ new PluginURL("/search/find/research-outcomes","Start searching", null, true)],
image:'https://' + (properties.environment == 'production'?'':'beta.')
+ 'connect.openaire.eu/assets/connect-assets/home/4.png',show:true},
{tag: "DEPOSIT YOUR RESEARCH OUTCOME", title: "Publish your research in Open Access.", description:""
, urlsArray:[ new PluginURL("/participate/deposit/learn-how","Deposit your research", null, true)],
image:'https://' + (properties.environment == 'production'?'':'beta.')
+ 'connect.openaire.eu/assets/connect-assets/home/1.png',show:true},
{tag: "LINK YOUR RESEARCH", title: "Contribute to your community.", description:""
, urlsArray:[ new PluginURL("/participate/claim","Link your Research searching", null, true)],
image:'https://' + (properties.environment == 'production'?'':'beta.')
+ 'connect.openaire.eu/assets/connect-assets/home/2.png',show:true},
];
compare(oldObject): any {
let newObj= super.compare(oldObject);
return newObj;
}
}
@Component({
selector: 'plugin-search-deposit-link',
templateUrl: 'plugin-search-deposit-link.component.html',
styleUrls:[`plugin-search-deposit-link.component.less`]
})
export class PluginSearchDepositLinkComponent extends PluginBaseComponent<PluginSearchDepositLink>{
entities= OpenaireEntities;
constructor(private communityService: CommunityService, protected layoutService: CustomizationService) {
super()
}
ngOnInit() {
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(
community => {
if(community) {
this.getLayout(community.communityId);
}
}));
}
get activeCards(){
return this.pluginObject.cardInfoArray.filter( card => card.show);
}
}

View File

@ -0,0 +1,133 @@
import {Component, Input, SimpleChanges} from '@angular/core';
import {PluginSearchDepositLink} from "./plugin-search-deposit-link.component";
import {PluginBaseFormComponent, PluginEditEvent} from "../../utils/base-plugin.form.component";
@Component({
selector: 'plugin-search-deposit-link-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<ng-container *ngIf="selectedIndex == -1">
<plugin-field-edit [value]=" pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)"></plugin-field-edit>
<div class="uk-margin-top uk-text-muted">
Cards:
</div>
<ng-container *ngFor="let card of pluginObject.cardInfoArray; let i = index">
<div class="uk-grid uk-grid-small uk-margin-xsmall-top">
<div *ngIf="selectedIndex != i" class="uk-text-small uk-width-expand">
<plugin-field-edit [value]=" pluginObject.cardInfoArray[i].show" type="checkbox" field="cardInfoArray"
(editClicked)="pluginEditEvent = $event"
(changed)="cardShowChanged(i,$event)"></plugin-field-edit>
{{card.tag?card.tag:card.title}}
</div>
<div class="uk-padding-remove-left uk-margin-medium-right">
<button
class="uk-button uk-button-link uk-flex uk-flex-middle" (click)="edit(i)">
<icon name="edit" [flex]="true"></icon>
</button>
</div>
</div>
</ng-container>
<div class="uk-alert uk-alert-warning uk-text-small uk-padding-xsmall">
Change the custom section background options <a routerLink="../../customize-layout" target="_blank"> here.</a>
</div>
</ng-container>
<ng-container *ngIf="selectedIndex > -1">
<div *ngIf="editTemplate" class="back uk-margin-bottom">
<a (click)="close()" class="uk-flex uk-flex-middle uk-flex-center">
<div class="uk-width-auto">
<icon name="west" ratio="1.3"
[flex]="true"></icon>
</div>
<span class="uk-text-small">Plugin Options</span>
</a>
</div>
<div class="uk-margin-top">
<plugin-field-edit [value]="pluginObject.cardInfoArray[selectedIndex].tag"
type="text" field="tag"
(changed)="cardValueChanged(selectedIndex, $event)"></plugin-field-edit>
</div>
<div class="uk-margin-top">
<plugin-field-edit [value]="pluginObject.cardInfoArray[selectedIndex].title"
type="text" field="title"
(changed)="cardValueChanged(selectedIndex, $event)"></plugin-field-edit>
</div>
<div class="uk-margin-top">
<plugin-field-edit [value]=" pluginObject.cardInfoArray[selectedIndex].description"
type="text" field="description"
(changed)="cardValueChanged(selectedIndex, $event)"></plugin-field-edit>
</div>
<ng-container *ngFor="let cardUrl of pluginObject.cardInfoArray[selectedIndex].urlsArray; let j = index ">
<div class=" uk-margin-top uk-text-meta uk-text-xsmall"> Link #{{j + 1}}</div>
<div class="uk-margin-small-top">
<plugin-field-edit [value]=" cardUrl.url"
type="text" field="url"
(changed)="cardUrlValueChanged(selectedIndex, j, $event)"></plugin-field-edit>
</div>
<div class="uk-margin-top">
<plugin-field-edit [value]=" cardUrl.linkText"
type="text" field="linkText" placeholder="Link text"
(changed)="cardUrlValueChanged(selectedIndex, j, $event)"></plugin-field-edit>
</div>
</ng-container>
</ng-container>
</div>
`,
})
export class PluginSearchDepositLinkFormComponent extends PluginBaseFormComponent<PluginSearchDepositLink> /*implements OnChanges*/ {
selectedIndex = -1;
@Input() editSubmenuOpen;
constructor() {
super()
}
ngOnChanges(changes: SimpleChanges) {
if (this.editSubmenuOpen == false && this.selectedIndex > -1) {
this.close();
}
}
cardShowChanged(i, $event: PluginEditEvent) {
this.pluginObject.cardInfoArray[i].show = $event.value;
$event.value = this.pluginObject.cardInfoArray;
this.valuesChanged.emit({field: $event.field, value: $event.value, type: 'parent'})
}
cardValueChanged(i, $event: PluginEditEvent) {
this.pluginObject.cardInfoArray[i][$event.field] = $event.value;
$event.value = this.pluginObject.cardInfoArray;
this.valuesChanged.emit({field: "cardInfoArray", value: $event.value, type: 'parent'})
}
cardUrlValueChanged(i, j, $event: PluginEditEvent) {
if (this.editTemplate) {
this.pluginObject.cardInfoArray[i].urlsArray[j][$event.field] = $event.value;
$event.value = this.pluginObject.cardInfoArray;
} else {
this.pluginObject.cardInfoArray[i].urlsArray[j][$event.field] = $event.value;
$event.value = this.pluginObject.cardInfoArray;
}
this.valuesChanged.emit({field: "cardInfoArray", value: $event.value, type: 'parent'})
}
edit(i) {
this.selectedIndex = i;
this.toggleSubMenu(true);
}
close() {
this.selectedIndex = -1;
this.toggleSubMenu(false);
}
}

View File

@ -0,0 +1,27 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {IconsModule} from "../../../../utils/icons/icons.module";
import {NumberRoundModule} from "../../../../utils/pipes/number-round.module";
import {IconsService} from "../../../../utils/icons/icons.service";
import {SearchResearchResultsServiceModule} from "../../../../services/searchResearchResultsService.module";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {PluginSearchDepositLinkComponent} from './plugin-search-deposit-link.component';
import {SliderUtilsModule} from "../../../../sharedComponents/slider-utils/slider-utils.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule,
PluginFieldEditModule, SliderUtilsModule
],
providers:[PluginsService],
declarations: [PluginSearchDepositLinkComponent],
exports: [PluginSearchDepositLinkComponent]
})
export class PluginSearchDepositLinkModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([])
}
}

View File

@ -0,0 +1,196 @@
<ng-container *ngIf="stakeholder; else nocommunity">
<div *ngIf="activeSubCategory" class="uk-section-small">
<div uk-slider class="uk-slider">
<ul class="uk-slider-items" uk-height-match="target: .uk-card; row: false">
<!--<li class="uk-width-1-1 uk-padding">
<div [class.uk-margin-large-bottom]="activeSubCategory.numbers.length > 0 ">
<ng-container *ngFor="let number of activeSubCategory.numbers; let i = index;">
<div *ngIf="!isMobile" class="uk-grid uk-grid-small uk-grid-match uk-margin-medium-bottom" uk-grid
uk-height-match="target: .uk-card">
<h5 *ngIf="number.title" class="uk-width-1-1 uk-margin-bottom">{{number.title}}</h5>
<ng-template ngFor [ngForOf]="number.indicators" let-indicator let-j="index">
<div *ngIf="hasPermission(indicator.visibility)"
[ngClass]="getNumberClassBySize(indicator.width)">
<div class="uk-card uk-card-default uk-padding-small number-card uk-position-relative"
[class.semiFiltered]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()">
<div *ngIf="!indicator.overlay">
<div
class="uk-text-small uk-text-truncate uk-margin-xsmall-bottom uk-margin-right">{{indicator.name}}</div>
<div class="number uk-text-small uk-text-bold">
<span *ngIf="numberResults.get(i + '-' + j)"
[innerHTML]="(indicator.indicatorPaths[0].format == 'NUMBER'?(numberResults.get(i + '-' + j) | numberRound: 2:1:stakeholder.locale):(numberResults.get(i + '-' + j) | numberPercentage: stakeholder.locale))"></span>
<span *ngIf="!numberResults.get(i + '-' + j)">&#45;&#45;</span>
</div>
<div *ngIf="indicator.description || indicator.additionalDescription"
class="uk-position-top-right uk-text-center uk-margin-small-top uk-margin-small-right uk-visible@m">
<a class="uk-display-inline-block uk-button uk-button-link" uk-tooltip="Note"
(click)="changeOverlay($event, indicator, 'description')">
<span class="uk-flex uk-flex-middle">
<icon name="analytics" type="outlined" [flex]="true"></icon>
</span>
</a>
</div>
</div>
<div *ngIf="indicator.overlay && (indicator.description || indicator.additionalDescription)"
click-outside-or-esc class="uk-overflow-auto"
(clickOutside)="closeOverlay($event, indicator)">
<div class="uk-position-top-right uk-text-center uk-margin-small-top uk-margin-small-right">
<a class="uk-display-inline-block uk-button uk-button-link"
(click)="changeOverlay($event, indicator, false)">
<span class="uk-flex uk-flex-middle">
<icon name="close" type="outlined" [flex]="true"></icon>
</span>
</a>
</div>
<div class="uk-margin-small-top uk-margin-right">
<p *ngIf="indicator.description">
{{indicator.description}}
</p>
<p *ngIf="indicator.additionalDescription">
{{indicator.additionalDescription}}
</p>
</div>
</div>
</div>
</div>
</ng-template>
</div>
<div *ngIf="isMobile">
<h6 *ngIf="number.title" class="uk-width-1-1 uk-margin-bottom">{{number.title}}</h6>
<div class="uk-card uk-card-default uk-padding-small number-card">
<div class="uk-grid uk-grid-small uk-child-width-1-1" uk-grid>
<ng-template ngFor [ngForOf]="number.indicators" let-indicator let-j="index">
<div *ngIf="hasPermission(indicator.visibility)"
[ngClass]="getNumberClassBySize(indicator.width)">
<div [class.semiFiltered]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()">
<div *ngIf="!indicator.overlay">
<div
class="uk-text-xsmall uk-text-truncate uk-margin-xsmall-bottom uk-margin-right">{{indicator.name}}</div>
<div class="number uk-text-small uk-text-bold">
<span *ngIf="numberResults.get(i + '-' + j)"
[innerHTML]="(indicator.indicatorPaths[0].format == 'NUMBER'?(numberResults.get(i + '-' + j) | numberRound: 2:1:stakeholder.locale):(numberResults.get(i + '-' + j) | numberPercentage: stakeholder.locale))"></span>
<span *ngIf="!numberResults.get(i + '-' + j)">&#45;&#45;</span>
</div>
</div>
</div>
</div>
</ng-template>
</div>
</div>
</div>
</ng-container>
</div>
</li>-->
<ng-container *ngFor="let chart of activeSubCategory.charts; let i = index;">
<li *ngIf="chart && showSection(chart)" class="uk-width-1-1 uk-padding">
<div class="uk-grid uk-grid-small uk-grid-match uk-margin-medium-bottom uk-flex uk-flex-middle" uk-grid uk-height-match="target: .uk-card">
<ng-template ngFor [ngForOf]="chart.indicators" let-indicator let-j="index">
<div *ngIf="showIndicator(indicator)"
[ngClass]="getChartClassBySize(indicator.width)">
<div class="uk-card uk-card-default uk-position-relative"
[class.semiFiltered]="getActiveIndicatorPath(indicator).filtersApplied < countSelectedFilters()">
<div class="uk-card-body uk-text-center uk-margin-small-bottom">
<h6 class="uk-margin-bottom chartTitle uk-flex uk-flex-bottom">
{{indicator.name + " "}}
</h6>
<!--<div *ngIf="indicator.indicatorPaths.length > 1" class="uk-button-group">
<button *ngFor="let indicatorPath of indicator.indicatorPaths;"
class="uk-button"
(click)="setActiveChart(i, j, indicatorPath.type)"
[class.uk-button-secondary]="getActiveIndicatorPath(indicator).url === indicatorPath.url">
{{indicatorPath.type}}
</button>
</div>-->
<iframe [class.uk-blend-multiply]="!isFullscreen"
*ngIf=" !properties.disableFrameLoad && getActiveIndicatorPath(indicator).source !== 'image'"
[src]="getActiveIndicatorPath(indicator).safeResourceUrl"
class="uk-width-1-1" allowfullscreen="true" mozallowfullscreen="true"
[ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"></iframe>
<div *ngIf="properties.disableFrameLoad && getActiveIndicatorPath(indicator).source !== 'image'">
<img class="uk-width-1-1 uk-blend-multiply"
[ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"
src="assets/chart-placeholder.png">
</div>
<img *ngIf="getActiveIndicatorPath(indicator).source === 'image'"
[src]="getActiveIndicatorPath(indicator).safeResourceUrl"
class="uk-width-1-1 uk-blend-multiply"
[ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')">
</div>
<div class="uk-position-bottom-left uk-margin-left uk-margin-small-bottom uk-visible@m">
<a *ngIf="indicator.description || indicator.additionalDescription"
class="uk-display-inline-block uk-button uk-button-link uk-margin-right"
(click)="changeOverlay($event, indicator, 'description')">
<span class="uk-flex uk-flex-middle">
<icon name="analytics" type="outlined" [flex]="true"></icon>
<span class="uk-margin-xsmall-left">Note</span>
</span>
</a>
<a class="uk-display-inline-block uk-button uk-button-link"
(click)="changeOverlay($event, indicator, 'embed')">
<span class="uk-flex uk-flex-middle">
<icon name="code" type="outlined" [flex]="true"></icon>
<span class="uk-margin-xsmall-left">Embed</span>
</span>
</a>
</div>
<div *ngIf="indicator.overlay" class="indicator-overlay uk-card uk-card-default uk-flex uk-flex-middle uk-flex-center">
<div *ngIf="indicator.overlay == 'description'" class="inner" click-outside-or-esc
(clickOutside)="closeOverlay($event, indicator)">
<div class="uk-padding-small">
<div class="uk-flex uk-flex-right">
<button class="uk-close uk-icon" (click)="changeOverlay($event, indicator, false)">
<icon name="close" ratio="1"></icon>
</button>
</div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<p *ngIf="indicator.description">
{{indicator.description}}
</p>
<p *ngIf="indicator.additionalDescription">
{{indicator.additionalDescription}}
</p>
</div>
</div>
</div>
<div *ngIf="indicator.overlay === 'embed'" class="inner" click-outside-or-esc
(clickOutside)="closeOverlay($event, indicator)">
<div class="uk-padding-small">
<div class="uk-flex uk-flex-right">
<button class="uk-close uk-icon" (click)="changeOverlay($event, indicator, false)">
<icon name="close" ratio="1"></icon>
</button>
</div>
<div class="clipboard-wrapper uk-margin-top uk-margin-bottom">
<pre id="embed_content_id" class="uk-padding-small"><code>&lt;iframe width="500" height="500" <br> src="{{chartsActiveType.get(i + '-' + j).safeResourceUrl.changingThisBreaksApplicationSecurity}}" <br> allowfullscreen="true" mozallowfullscreen="true"&gt;<br>&lt;/iframe&gt;</code></pre>
</div>
<div class="uk-flex uk-flex-right">
<a class="uk-link-reset copy clipboard_btn" data-clipboard-target="#embed_content_id" title="Copy code">
<icon [flex]="true" name="content_copy"></icon>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="printGap uk-hidden"></div>
</ng-template>
</div>
</li>
</ng-container>
</ul>
<ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin-medium-top"></ul>
</div>
</div>
</ng-container>
<ng-template #nocommunity>
<div class="uk-text-muted uk-text-center">
No community info available
</div>
</ng-template>

View File

@ -0,0 +1,102 @@
import {ChangeDetectorRef, Component, Input} from "@angular/core";
import {MonitorIndicatorStakeholderBaseComponent} from "src/app/openaireLibrary/monitor/monitor-indicator-stakeholder-base.component";
import {map} from "rxjs/operators";
import {StatisticsService} from "../../../../monitor-admin/utils/services/statistics.service";
import {ActivatedRoute, Router} from "@angular/router";
import {PiwikService} from "../../../../utils/piwik/piwik.service";
import {DomSanitizer, Meta, Title} from "@angular/platform-browser";
import {SEOService} from "../../../../sharedComponents/SEO/SEO.service";
import {SearchResearchResultsService} from "../../../../services/searchResearchResults.service";
import {HttpClient} from "@angular/common/http";
import {IndicatorPath, Section, Visibility} from "../../../../monitor/entities/stakeholder";
import {LayoutService} from "../../../sharedComponents/sidebar/layout.service";
import {CommunityService} from "../../../../connect/community/community.service";
import {PluginStats} from "./plugin-stats.component";
@Component({
selector: 'plugin-stats-monitor',
templateUrl: 'monitor.component.html'
})
export class MonitorComponent extends MonitorIndicatorStakeholderBaseComponent {
activeChartSectionIndex: number = 0;
stakeholder = null;
@Input() pluginObject: PluginStats;
profiles;
constructor(protected _route: ActivatedRoute,
protected _router: Router,
protected _meta: Meta,
protected _title: Title,
protected _piwikService: PiwikService,
protected seoService: SEOService,
protected sanitizer: DomSanitizer,
protected cdr: ChangeDetectorRef,
protected layoutService: LayoutService,
protected statisticsService: StatisticsService,
protected searchResearchResultsService: SearchResearchResultsService,
private communityService: CommunityService,
private http: HttpClient) {
super();
}
ngOnInit() {
super.ngOnInit();
this.requireLogin = false;
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(communityInfo => {
if (communityInfo) {
this.subscriptions.push(this.http.get(this.properties.monitorStatsFrameUrl+"/schema/profiles").subscribe((profiles:any[]) => {
this.profiles = profiles.map( (profile) => profile.name);
let profile = PluginStats.getDefaultProfile();
if(this.profiles.indexOf("monitor_"+communityInfo.communityId.replace("-","_"))!=-1){
profile = this.profiles[this.profiles.indexOf("monitor_"+communityInfo.communityId.replace("-","_"))];
}else if(communityInfo.type == "ri" && this.profiles.indexOf("monitor_ris_tail")!=-1){
profile = "monitor_ris_tail";
}
this.init(communityInfo, profile);
}, error => {
let profile =
this.init(communityInfo, PluginStats.getDefaultProfile());
}))
}
}));
}
public init(communityInfo, profile){
console.log(profile)
this.loading = true;
this.stakeholder = PluginStats.getMockStakeholder();
this.stakeholder.statsProfile = profile;
this.stakeholder.index_id = communityInfo.communityId
this.stakeholder.index_name = communityInfo.title;
this.stakeholder.index_shortName = communityInfo.shortTitle;
this.title = this.stakeholder.name;
this.description = this.stakeholder.name;
this.loading = true;
this.activeTopic = null;
this.activeCategory = null;
this.activeSubCategory = null;
this.numberResults = new Map<string, number>();
this.setView({});
let ids = [];
for (let section of this.activeSubCategory.charts) {
for (let indicator of section.indicators) {
ids.push(indicator._id)
}
}
}
public showSection(section: Section): boolean {
for (let indicator of section.indicators) {
if (this.showIndicator(indicator)) {
return true;
}
}
return false;
}
public showIndicator(indicator): boolean {
return this.pluginObject.disabledIndicators.indexOf(indicator._id) == -1;
}
}

View File

@ -0,0 +1,29 @@
import {NgModule} from "@angular/core";
import {CommonModule} from "@angular/common";
import {RouterModule} from "@angular/router";
import {MonitorComponent} from "./monitor.component";
import {PageContentModule} from "../../../../dashboard/sharedComponents/page-content/page-content.module";
import {SliderTabsModule} from "../../../../sharedComponents/tabs/slider-tabs.module";
import {NumberRoundModule} from "../../../../utils/pipes/number-round.module";
import {IconsModule} from "../../../../utils/icons/icons.module";
import {ClickModule} from "../../../../utils/click/click.module";
import {RangeFilterModule} from "../../../../utils/rangeFilter/rangeFilter.module";
import {SearchFilterModule} from "../../../../searchPages/searchUtils/searchFilter.module";
import {IconsService} from "../../../../utils/icons/icons.service";
import {filters} from "../../../../utils/icons/icons";
import {SliderUtilsModule} from "../../../../sharedComponents/slider-utils/slider-utils.module";
import {LoadingModule} from "../../../../utils/loading/loading.module";
@NgModule({
imports: [CommonModule, PageContentModule, SliderTabsModule, NumberRoundModule, IconsModule, ClickModule, RangeFilterModule, SearchFilterModule, SliderUtilsModule, LoadingModule],
declarations: [MonitorComponent],
exports: [
MonitorComponent
]
})
export class MonitorModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([ filters]);
}
}

View File

@ -0,0 +1,9 @@
<div *ngIf="pluginObject" class="uk-container uk-section">
<h3>{{pluginObject.title}} </h3>
<a *ngIf="pluginObject.url.url && pluginObject.url.url.length > 0" [href]="pluginObject.url.url" [target]="pluginObject.url.target"
class="uk-float-right uk-text-uppercase uk-button uk-button-text">
{{pluginObject.url.linkText}}
</a>
<!-- <a *ngIf="pluginObject.url.url && pluginObject.url.url.length > 0" class = "uk-float-right" href="" [target]="">{{pluginObject.url.linkText}}</a>-->
<plugin-stats-monitor [pluginObject]="pluginObject"></plugin-stats-monitor>
</div>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,81 @@
import {Component} from '@angular/core';
import {PluginBaseFormComponent, PluginEditEvent} from "../../utils/base-plugin.form.component";
import {PluginStats} from "./plugin-stats.component";
@Component({
selector: 'plugin-stats-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<plugin-field-edit [value]="pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)"></plugin-field-edit>
<div class=" uk-margin-top uk-text-meta uk-text-xsmall">External Link</div>
<div class="uk-margin-small-top">
<plugin-field-edit [value]="pluginObject.url.url"
type="text" field="url" (changed)="urlValueChanged($event)"></plugin-field-edit>
</div>
<div class="uk-margin-small-top uk-margin-small-top">
<plugin-field-edit [value]="pluginObject.url.linkText"
type="text" field="linkText" (changed)="urlValueChanged($event)"></plugin-field-edit>
</div>
<!-- <div class=" uk-margin-top uk-text-meta uk-text-xsmall"> Number indicators</div>-->
<!-- <ng-container *ngFor="let number of stakeholder.topics[0].category[0].subcategory[0].numbers">-->
<!-- <div class="uk-grid uk-grid-small uk-margin-xsmall-top">-->
<!-- <div class="uk-text-small uk-width-3-4">{{service.name}}</div>-->
<!-- <div class=" uk-width-1-4">-->
<!-- <plugin-field-edit [value]=" pluginObject.serviceIdsArray.indexOf(service.id)!=-1"-->
<!-- type="boolean" field="serviceIdsArray" (changed)="serviceChanged(service.id,$event)" >-->
<!-- </plugin-field-edit>-->
<!-- </div>-->
<!-- </div>-->
<!-- </ng-container>-->
<div class=" uk-margin-medium-top uk-text-meta uk-text-xsmall"> Chart indicators</div>
<ng-container *ngFor="let section of stakeholder.topics[0].categories[0].subCategories[0].charts">
<ng-container *ngFor="let indicator of section.indicators">
<div class=" uk-margin-xsmall-top">
<plugin-field-edit [value]=" pluginObject.disabledIndicators.indexOf(indicator._id)==-1"
type="checkbox" field="sdgs" (editClicked)="pluginEditEvent = $event"
(changed)="indicatorsChanged(indicator._id,$event)">
</plugin-field-edit>
{{indicator.indicatorPaths[0].name?indicator.name:(indicator.indicatorPaths[0].parameters['title'] )}}
<span class=" uk-text-xsmall">
{{ indicator.indicatorPaths[0].parameters['subtitle']? ' ' + indicator.indicatorPaths[0].parameters['subtitle']:''}}</span>
</div>
</ng-container>
</ng-container>
</div>
<!-- --> `,
})
export class PluginStatsFormComponent extends PluginBaseFormComponent<PluginStats> {
stakeholder = PluginStats.getMockStakeholder();
constructor() {
super()
}
indicatorsChanged(id,$event:PluginEditEvent ){
console.log("before", id,this.pluginObject.disabledIndicators)
let index = this.pluginObject.disabledIndicators.indexOf(id);
if(index !=-1){
this.pluginObject.disabledIndicators.splice(index,1);
}else{
this.pluginObject.disabledIndicators.push(id);
}
$event.value =this.pluginObject.disabledIndicators;
console.log("after",this.pluginObject.disabledIndicators)
this.valuesChanged.emit({field:$event.field, value: $event.value, type: 'parent'})
}
urlValueChanged($event:PluginEditEvent){
console.log($event.field,$event.value)
this.pluginObject['url'][$event.field]=$event.value;
$event.field = "url";
$event.value = this.pluginObject['url'];
this.valuesChanged.emit($event)
}
}

View File

@ -0,0 +1,23 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {InputModule} from "../../../../sharedComponents/input/input.module";
import {PluginStatsComponent} from "./plugin-stats.component";
import {MonitorModule} from "./monitor.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, PluginFieldEditModule, InputModule, MonitorModule
],
providers: [
PluginsService
],
declarations: [PluginStatsComponent],
exports: [PluginStatsComponent]
})
export class PluginStatsModule {
}

View File

@ -0,0 +1,47 @@
<div *ngIf="!community " class="uk-text-muted uk-text-center">
No community info available
</div>
<div *ngIf="community" class="plugin-suggested-repositories uk-container uk-container-large uk-section">
<div class="uk-flex uk-flex-middle uk-flex-between uk-margin-large-bottom">
<h3 class="uk-margin-remove">
<icon [name]="'database'" [type]="'outlined'" [ratio]="3" class="uk-margin-small-right"></icon>
{{pluginObject.title}}
</h3>
<!--<a *ngIf=" contentProviders && contentProviders.length > 2" [href]="" class="uk-display-inline-block uk-text-uppercase uk-button uk-button-text uk-text-default">
View all
</a>-->
</div>
<div [innerHTML]="pluginObject.description"></div>
<div *ngIf="!contentProviders || contentProviders.length == 0 " class="uk-text-muted uk-text-center">
No datasources available
</div>
<div uk-slider class="uk-slider">
<ul *ngIf="slides" class="uk-slider-items" uk-height-match="target: .uk-card; row: false">
<li *ngFor="let slide of [].constructor(slides); let i=index" class="uk-width-1-1 uk-padding">
<div class="uk-grid uk-child-width-1-2@m uk-child-width-1-1" uk-grid uk-scrollspy="target: [uk-scrollspy-class]; cls: uk-animation-fade; repeat: true">
<div *ngFor="let item of contentProviders.slice((i)*2,(i+1)*2)" uk-scrollspy-class>
<div class="uk-card uk-card-default uk-card-body uk-card-hover">
{{item.name}}
<hr>
<div class="uk-text-small" [innerHTML]="item.message">
</div>
<div class="uk-flex uk-flex-right uk-margin-small-top">
<a [href]="properties.connectPortalUrl + properties.searchLinkToDataProvider + item.openaireId " class="uk-float-right uk-margin-small-left uk-display-inline-block uk-text-uppercase uk-button uk-button-text" target="_blank">
<span class="uk-flex uk-flex-middle">
<icon [name]="'file_upload'" [type]="'outlined'" class="uk-margin-small-right"></icon>
<span>Go to repository</span>
</span>
</a>
</div>
</div>
</div>
</div>
</li>
</ul>
<ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin-medium-top"></ul>
</div>
</div>

View File

@ -0,0 +1,59 @@
import {Component} from '@angular/core';
import {PluginBaseComponent, PluginBaseInfo} from "../../utils/base-plugin.component";
import {SearchCommunityDataprovidersService} from "../../../../connect/contentProviders/searchDataproviders.service";
import {ConfigurationService} from "../../../../utils/configuration/configuration.service";
import {CommunityService} from "../../../../connect/community/community.service";
export class PluginSuggestedRepositories extends PluginBaseInfo{
title:string ="Suggested repositories & journals";
description:string = "";
compare(oldObject): any {
return super.compare(oldObject);
}
}
@Component({
selector: 'plugin-suggested-repositories',
templateUrl: 'plugin-suggested-repositories.component.html'
})
export class PluginSuggestedRepositoriesComponent extends PluginBaseComponent<PluginSuggestedRepositories>{
portal;
community;
contentProviders;
slides = 0;
constructor(private searchCommunityDataprovidersService: SearchCommunityDataprovidersService,
private config: ConfigurationService,
private communityService: CommunityService) {
super()
this.subscriptions.push(this.config.portalAsObservable.subscribe(
res => {
this.portal = res;
},
error => {
console.log(error);
}
));
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(
community => {
this.community = community;
if (community) {
this.subscriptions.push(this.searchCommunityDataprovidersService.searchDataproviders(this.properties, this.community.communityId, true).subscribe(
res => {
this.slides =1;
this.contentProviders = res;
if(this.contentProviders.length > 2){
this.slides = parseInt('' + (this.contentProviders.length/2));
}
if(this.slides< (this.contentProviders.length / 2)){
this.slides++;
}
},
error => {
console.log(error);
}
));
}
}
));
}
}

View File

@ -0,0 +1,26 @@
import {Component} from '@angular/core';
import {PluginBaseFormComponent} from "../../utils/base-plugin.form.component";
import {PluginSuggestedRepositories} from "./plugin-suggested-repositories.component";
@Component({
selector: 'plugin-suggested-repositories-form',
template: `
<div *ngIf="pluginObject" class="uk-padding-xsmall">
<plugin-field-edit [value]="pluginObject.title"
type="text" field="title" (changed)="valueChanged($event)"></plugin-field-edit>
<plugin-field-edit [value]="pluginObject.description"
type="textarea" field="description" (changed)="valueChanged($event)" [switchToHTMLEditor]="true"></plugin-field-edit>
<div class="uk-alert uk-alert-warning uk-text-small"> Manage the content providers list in
<a routerLink="../../../info/content-providers" target="_blank">Community info</a> by adding them in deposit.</div>
</div>
`,
})
export class PluginSuggestedRepositoriesFormComponent extends PluginBaseFormComponent<PluginSuggestedRepositories> {
constructor() {
super()
}
}

View File

@ -0,0 +1,25 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginsService} from "../../../../services/plugins.service";
import {IconsModule} from "../../../../utils/icons/icons.module";
import {NumberRoundModule} from "../../../../utils/pipes/number-round.module";
import {IconsService} from "../../../../utils/icons/icons.service";
import {SearchResearchResultsServiceModule} from "../../../../services/searchResearchResultsService.module";
import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module";
import {PluginSuggestedRepositoriesComponent} from './plugin-suggested-repositories.component';
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule, PluginFieldEditModule
],
providers:[PluginsService],
declarations: [PluginSuggestedRepositoriesComponent],
exports: [PluginSuggestedRepositoriesComponent]
})
export class PluginSuggestedRepositoriesModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([])
}
}

View File

@ -0,0 +1,13 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {PluginsFormComponent} from "./pluginsForm.component";
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', component: PluginsFormComponent}
])
]
})
export class PluginsFormRoutingModule { }

View File

@ -0,0 +1,105 @@
<div class="uk-flex">
<aside id="sidebar_main" class="uk-sticky" uk-sticky="start: 0; end: .sidebar_main_swipe">
<div sidebar-content>
<div class="back">
<a *ngIf="!editSubmenuOpen" (click)="promtToGoBack()"
class="uk-flex uk-flex-middle uk-flex-center">
<div class="uk-width-auto">
<icon name="west" ratio="1.3"
[flex]="true"></icon>
</div>
<span class="uk-text-small">Plugins list</span>
</a>
<div *ngIf="editSubmenuOpen" class="back uk-margin-bottom">
<a (click)="editSubmenuOpen = false" class="uk-flex uk-flex-middle uk-flex-center">
<div class="uk-width-auto">
<icon name="west" ratio="1.3"
[flex]="true"></icon>
</div>
<span class="uk-text-small">Plugin Options</span>
</a>
</div>
<div *ngIf="templateForm" class="uk-width-auto uk-margin-top uk-margin-left">
<button class="uk-button uk-button-default uk-margin-right"
(click)="reset()" [class.uk-disabled]="!templateForm.dirty"
[disabled]="!templateForm.dirty || showLoading">Reset
</button>
<button class="uk-button uk-button-primary"
[class.uk-disabled]="templateForm.invalid || !templateForm.dirty || templateForm.disabled"
(click)="saveConfirmed()"
[disabled]="templateForm.invalid ||!templateForm.dirty || templateForm.disabled || showLoading">Save
</button>
</div>
</div>
<div class="menu_section uk-margin-top uk-margin-left">
<form *ngIf="templateForm && selectedPlugin" [formGroup]="templateForm" >
<div *ngIf="!editSubmenuOpen" class="uk-text-small uk-margin-small-left">Enable
<mat-slide-toggle [checked]="templateForm.get('active').value"
(change)="templateForm.get('active').setValue($event.checked); templateForm.markAsDirty()"></mat-slide-toggle>
</div>
<plugin-wrapper-form [pluginTemplate]="selectedTemplate" [plugin]="this.templateForm.getRawValue()"
(changed)="pluginFieldChanged($event)"
[pluginObject]="this.selectedPlugin.object"
[editSubmenuOpen]="editSubmenuOpen" ></plugin-wrapper-form>
<ng-container *ngIf="selectedTemplate || selectedPlugin">
<div *ngIf="attrFormArray.controls.length > 0"
class="uk-heading-divider uk-text-small uk-width-1-1 uk-margin-bottom uk-text-meta">
<div class="uk-grid">
<div>Plugin settings</div>
</div>
</div>
<div *ngFor="let attrForm of attrFormArray.controls; let i=index"
class="uk-width-1-1 uk-grid uk-child-width-1-2 uk-margin-top" uk-grid>
<div *ngIf="this.selectedTemplate.settings[attrForm.get('key').value].type == 'text'" input
[formInput]="attrForm.get('value')"
[placeholder]="selectedTemplate.settings[attrForm.get('key').value].name" type="text"></div>
<div *ngIf="this.selectedTemplate.settings[attrForm.get('key').value].type == 'URL'" input
[formInput]="attrForm.get('value')"
[placeholder]="selectedTemplate.settings[attrForm.get('key').value].name" type="URL"
[validators]="urlValidator"></div>
<div *ngIf="this.selectedTemplate.settings[attrForm.get('key').value].type == 'boolean'" input
[formInput]="attrForm.get('value')"
[placeholder]="selectedTemplate.settings[attrForm.get('key').value].name" type="select"
[options]="[{label: 'yes', value:true}, {label: 'no', value:false}]"></div>
<div *ngIf="this.selectedTemplate.settings[attrForm.get('key').value].type == 'HTML'"
class="uk-width-1-1">
<label>
{{selectedTemplate.settings[attrForm.get('key').value].name}}:
</label>
<ckeditor [readonly]="false"
debounce="500"
[formControl]="attrForm.get('value')"
[config]="{ extraAllowedContent: '* [uk-*](*) ; span', disallowedContent: 'script; *[on*]',
removeButtons: 'Save,NewPage,DocProps,Preview,Print,' +
'Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,' +
'CreateDiv,Flash,PageBreak,' +
'Subscript,Superscript,Anchor,Smiley,Iframe,Styles,Font,About,Language',
extraPlugins: 'divarea'}">
</ckeditor>
</div>
</div>
</ng-container>
</form>
</div>
</div>
</aside>
<div page-content [fullWidth]="true" class="uk-width-1-1">
<div inner>
<div> <!--class="uk-section uk-section-small uk-position-relative" style="min-height: 60vh">-->
<div *ngIf="showLoading" class="uk-position-center">
<loading></loading>
</div>
<plugin-wrapper *ngIf="this.templateForm" [pluginTemplate]="selectedTemplate"
[plugin]="this.templateForm.getRawValue()"
[pluginObject]="this.selectedPlugin.object"
class="uk-width-1-1"></plugin-wrapper>
</div>
</div>
</div>
</div>
<modal-alert #backAlert [overflowBody]="false" (alertOutput)="confirmGoBack()"
classTitle="uk-background-primary uk-light"></modal-alert>

View File

@ -0,0 +1,251 @@
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {HelpContentService} from "../../../services/help-content.service";
import {FormArray, UntypedFormBuilder, UntypedFormGroup, ValidatorFn, Validators} from "@angular/forms";
import {Page} from "../../../utils/entities/adminTool/page";
import {EnvProperties} from '../../../utils/properties/env-properties';
import {HelperFunctions} from "../../../utils/HelperFunctions.class";
import {Subscriber} from "rxjs";
import {properties} from "../../../../../environments/environment";
import {Title} from "@angular/platform-browser";
import {ClearCacheService} from "../../../services/clear-cache.service";
import {NotificationHandler} from "../../../utils/notification-handler";
import {PluginsService} from "../../../services/plugins.service";
import {Plugin} from "../../../utils/entities/adminTool/plugin";
import {StringUtils} from "../../../utils/string-utils.class";
import {Portal} from "../../../utils/entities/adminTool/portal";
import {PluginTemplate} from "../../../utils/entities/adminTool/pluginTemplate";
import {PluginUtils} from "../utils/pluginUtils";
import {CommunityService} from "../../../connect/community/community.service";
import {CommunityInfo} from "../../../connect/community/communityInfo";
import {PluginEditEvent} from "../utils/base-plugin.form.component";
import {AlertModal} from "../../../utils/modal/alert";
@Component({
selector: 'plugins-form',
templateUrl: './pluginsForm.component.html',
})
export class PluginsFormComponent implements OnInit {
public selectedTemplate: PluginTemplate = null;
public selectedPlugin: Plugin = null;
public templateForm: UntypedFormGroup;
urlValidator: ValidatorFn = StringUtils.urlValidator;
public properties: EnvProperties = properties;
public showLoading: boolean = true;
private subscriptions: any[] = [];
public pluginUtils = new PluginUtils();
selectedCommunityPid = null;
public portal: string;
public selectedPageId: string;
public selectedTemplateId: string;
public selectedPluginId: string;
public community: Portal;
public page: Page;
public template;
public selectedPlacementView = "all";
communityInfo:CommunityInfo = null;
editSubmenuOpen = false;
@ViewChild('backAlert') backAlert: AlertModal;
constructor(private element: ElementRef, private route: ActivatedRoute, private _router: Router,
private communityService: CommunityService,
private title: Title, private _helpContentService: HelpContentService,
private _pluginsService: PluginsService, private _fb: UntypedFormBuilder,
private _clearCacheService: ClearCacheService) {
}
ngOnInit() {
this.title.setTitle('Administrator Dashboard | Plugins');
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(
community => {
this.communityInfo = community;
}));
this.subscriptions.push(this.route.params.subscribe(params => {
this.portal = (this.route.snapshot.data.portal) ? this.route.snapshot.data.portal : this.route.snapshot.params[this.route.snapshot.data.param];
this.selectedCommunityPid = params.community;
this.subscriptions.push(this.route.queryParams.subscribe(params => {
HelperFunctions.scroll();
this.selectedPageId = params['pageId'];
this.selectedPluginId = params['pluginId'];
this.selectedTemplateId = params['templateId'];
if (this.portal && this.selectedPageId) {
this.getPage(this.selectedPageId);
}
if (!this.selectedPageId) {
this._router.navigate(['../'], {relativeTo: this.route});
}
}));
}));
}
ngOnDestroy(): void {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
} else if (value instanceof Function) {
value();
}
});
}
getPage(pageId: string) {
this.showLoading = true;
this.subscriptions.push(this._helpContentService.getPageByPortal(pageId, this.properties.adminToolsAPIURL, this.portal).subscribe(
page => {
if (this.properties.adminToolsPortalType != page.portalType) {
this._router.navigate(['..'],{ relativeTo: this.route});
} else {
this.page = page;
this.getPluginAndTemplate();
}
},
error => this.handleError('System error retrieving page', error)));
}
getPluginAndTemplate(){
if(this.selectedTemplateId){
this.subscriptions.push(this._pluginsService.getPluginTemplateById(this.properties.adminToolsAPIURL, this.selectedTemplateId).subscribe(template => {
this.selectedTemplate = template;
if(this.selectedPluginId){
this.subscriptions.push(this._pluginsService.getPluginById(this.properties.adminToolsAPIURL, this.selectedPluginId).subscribe(plugin => {
this.selectedPlugin = plugin;
this.edit(this.selectedPlugin, this.selectedTemplate);
}));
}else{
this.selectedPlugin = new Plugin(this.page._id,this.selectedCommunityPid, template);
// this.selectedPlugin.order = this.pluginsByPlacement.get(this.selectedPlacementView).length;
this.selectedPlugin.object = PluginUtils.initializeObjectAndCompare(template.code,null);
this.edit(this.selectedPlugin, this.selectedTemplate);
}
}, error =>{
this._router.navigate(['../'], {queryParams: {pageId:this.selectedPageId}, relativeTo: this.route});
}));
}else{
this._router.navigate(['../'], {queryParams: {pageId:this.selectedPageId}, relativeTo: this.route});
}
}
public edit(plugin:Plugin, template:PluginTemplate) {
this.templateForm = this._fb.group({
_id: this._fb.control(plugin._id),
pid: this._fb.control(plugin.pid),
page: this._fb.control(plugin.page),
templateCode: this._fb.control(plugin.templateCode, Validators.required),
templateId: this._fb.control(plugin.templateId, Validators.required),
placement: this._fb.control(plugin.placement),
order: this._fb.control(plugin.order),
active: this._fb.control(plugin.active),
values: this._fb.array([]),
});
if (template.settings) {
for (let attrKey of Object.keys(template.settings)) {
(this.templateForm.get("values") as FormArray).push(this._fb.group({
'key': this._fb.control(attrKey),
'value': this._fb.control(plugin.settingsValues[attrKey]?plugin.settingsValues[attrKey]:template.settings[attrKey].value)
}
));
}
}
this.showLoading = false;
}
public saveConfirmed() {
this.showLoading = true;
let plugin: Plugin = <Plugin>this.templateForm.getRawValue();
plugin.object = this.selectedPlugin.object;
plugin.settingsValues = new Map<string, string>();
for (let fields of this.templateForm.getRawValue().values) {
plugin.settingsValues[fields.key] = fields.value;
}
let update = (plugin._id) ? true : false;
this.savePlugin(plugin,update)
}
public savePlugin(plugin, update){
this.subscriptions.push(this._pluginsService.savePlugin(plugin, this.properties.adminToolsAPIURL,this.selectedCommunityPid ).subscribe(
saved => {
this._clearCacheService.purgeBrowserCache(null, this.selectedCommunityPid)
this.edit(saved, this.selectedTemplate)
},
error => this.handleUpdateError("System error creating template", error)
));
}
handleUpdateError(message: string, error = null) {
if (error) {
console.log('Server responded: ' + error);
}
NotificationHandler.rise(message, 'danger');
this.showLoading = false;
}
handleError(message: string, error = null) {
if (error) {
console.log('Server responded: ' + error);
}
NotificationHandler.rise(message, 'danger');
this.showLoading = false;
}
get attrFormArray() {
return this.templateForm.get("values") as FormArray;
}
attributeTypeChanged(form) {
let type = form.get("value").get("type");
form.get("value").setValue("");
if (type == "boolean") {
form.get("value").setValue(false);
}
}
getKeys(obj) {
return obj?Object.keys(obj):[];
}
reset() {
this.edit(this.selectedPlugin, this.selectedTemplate)
}
pluginFieldChanged($event:PluginEditEvent){
if($event.type == "open-submenu"){
this.editSubmenuOpen = true;
return;
}
if($event.type == "close-submenu"){
this.editSubmenuOpen = false;
return;
}
this.selectedPlugin.object[$event.field]=$event.value;
this.templateForm.markAsDirty();
}
promtToGoBack() {
if(this.templateForm.dirty) {
this.backAlert.alertTitle = 'Leave page';
this.backAlert.message = 'Are you sure you want to leave the page?';
this.backAlert.okButtonText = 'Yes';
this.backAlert.open();
}else{
this.confirmGoBack();
}
}
confirmGoBack() {
this._router.navigate(["../"],{queryParams:{pageId:this.selectedPageId},relativeTo:this.route})
}
}

View File

@ -0,0 +1,42 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {AdminToolServiceModule} from "../../../services/adminToolService.module";
import {InputModule} from "../../../sharedComponents/input/input.module";
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {MatCheckboxModule} from "@angular/material/checkbox";
import {MatFormFieldModule} from "@angular/material/form-field";
import {MatChipsModule} from '@angular/material/chips';
import {AdminTabsModule} from "../../sharedComponents/admin-tabs/admin-tabs.module";
import {PageContentModule} from "../../sharedComponents/page-content/page-content.module";
import {SearchInputModule} from "../../../sharedComponents/search-input/search-input.module";
import {IconsModule} from "../../../utils/icons/icons.module";
import {LoadingModule} from "../../../utils/loading/loading.module";
import {PluginsService} from "../../../services/plugins.service";
import {CKEditorModule} from "ng2-ckeditor";
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
import {PluginWrapperModule} from "../wrapper/plugin-wrapper.module";
import {SideBarModule} from "../../sharedComponents/sidebar/sideBar.module";
import {PluginEditWrapperModule} from "../wrapper/plugin-edit-wrapper.module";
import {PluginsFormComponent} from "./pluginsForm.component";
import {PluginsFormRoutingModule} from "./pluginsForm-routing.module";
import {AlertModalModule} from "../../../utils/modal/alertModal.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule,
ReactiveFormsModule, AdminToolServiceModule, InputModule, MatAutocompleteModule, MatFormFieldModule, MatChipsModule,
MatCheckboxModule, AdminTabsModule, PageContentModule, PluginsFormRoutingModule, SearchInputModule, IconsModule, LoadingModule, CKEditorModule,
MatSlideToggleModule, PluginWrapperModule, SideBarModule, PluginEditWrapperModule, AlertModalModule
],
providers:[PluginsService],
declarations: [PluginsFormComponent],
exports: [PluginsFormComponent]
})
export class PluginsFormModule {}

View File

@ -0,0 +1,14 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {PluginsComponent} from "./plugins.component";
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', component: PluginsComponent},
{ path: ':templateCode', component: PluginsComponent, data: {templateView:true}}
])
]
})
export class PluginsRoutingModule { }

View File

@ -0,0 +1,203 @@
<div page-content class="uk-width-1-1">
<div header>
<div class="uk-section-xsmall uk-margin-top">
<div class="uk-flex-middle uk-grid" uk-grid>
<ng-container>
<div class="uk-width-expand">
<a routerLink="../pages" class="uk-flex uk-flex-middle uk-h5 uk-link-reset">
<span class="uk-margin-right">
<icon name="west" ratio="1.7" [flex]="true"></icon>
</span>
<h1 *ngIf="page" class="uk-h5 uk-margin-remove">{{page.name}}</h1>
</a>
<ul *ngIf="!sinlgePlacementAvailable" class="uk-subnav uk-subnav-pill uk-margin-medium-top">
<li [class.uk-active]="selectedPlacementView === 'all'" class="uk-margin-small-bottom"><a
(click)="selectedPlacementView = 'all'"><span
class="title">All placements</span></a></li>
<li *ngFor="let position of pluginUtils.placementsOptions; let i=index"
[class.uk-active]="selectedPlacementView === position.value" class="uk-margin-small-bottom"><a
(click)="selectedPlacementView = position.value"><span
class="title">{{position.label}}</span></a></li>
</ul>
</div>
<!--<div *ngIf="templateView" class="uk-width-expand">
<a routerLink="../.." class="uk-flex uk-flex-middle uk-h5 uk-link-reset">
<span class="uk-margin-right">
<icon name="west" ratio="1.7" [flex]="true"></icon>
</span>
<h1 *ngIf="template" class="uk-h5 uk-margin-remove">{{template.name}}</h1>
</a>
</div>-->
</ng-container>
</div>
</div>
</div>
<div inner>
<div *ngIf="showLoading" class="uk-position-center">
<loading></loading>
</div>
<ng-container *ngIf="!showLoading">
<div *ngIf="pluginTemplates.length> 0" class="uk-padding-xsmall uk-grid uk-flex uk-flex-middle">
<!-- filters-->
<div class="uk-width-expand">
<input [ngModel]="filterActive" [checked]="filterActive" (ngModelChange)="filterActive = !filterActive" type="checkbox" class="uk-checkbox"> Show active
</div>
<div class="uk-padding-small uk-padding-remove-horizontal uk-width-auto">
<a class="uk-button uk-button-link uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">
Add custom plugin
</span>
</a>
<div uk-dropdown="mode:click">
<ul class="uk-nav uk-dropdown-nav">
<ng-container *ngFor="let template of pluginTemplates">
<li *ngIf="template.custom"><a (click)="addNewCustomPlugin(template)"> {{template.name}}</a></li>
</ng-container>
</ul>
</div>
</div>
</div>
<div *ngIf="pluginTemplates.length == 0"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div>No plugins found</div>
</div>
<ng-container *ngFor="let placement of pluginUtils.placementsOptions">
<ng-container *ngIf="selectedPlacementView == placement.value || selectedPlacementView == 'all'">
<div *ngIf="pluginsByPlacement.get(placement.value).length >0 && page && !sinlgePlacementAvailable"
class="uk-heading-divider uk-h6 uk-margin-left uk-padding-remove-left uk-text-capitalize ">{{placement.value}}</div>
<div class="uk-animation-toggle">
<ng-container *ngFor="let pluginGroup of pluginsByPlacement.get(placement.value) ; let i=index">
<ng-container *ngIf="(pluginGroup.template.portalSpecific.length == 0 || pluginGroup.template.portalSpecific.indexOf(communityInfo.communityId) != -1 ) &&
(pluginGroup.template.plan == 'Standard' || pluginGroup.template.plan == 'Default' || pluginGroup.template.plan == communityInfo.plan )
&& ( !filterActive || (filterActive && pluginGroup.plugin.active))">
<div class="uk-card uk-card-default uk-margin-bottom uk-animation-fade" >
<div class="uk-card-body uk-flex">
<div class="uk-width-expand uk-text-small">
<ng-container *ngIf="pluginGroup.template && !templateView">
<h6 *ngIf="!(pluginGroup.plugin.custom && pluginGroup.template.custom)">{{pluginGroup.template.name}}</h6>
<h6 *ngIf="pluginGroup.plugin.custom && pluginGroup.template.custom">{{pluginGroup.plugin.object && pluginGroup.plugin.object.title?pluginGroup.plugin.object.title:pluginGroup.template.name}}</h6>
<div class="uk-margin-small-bottom">
{{pluginGroup.template.description}}
</div>
</ng-container>
<div *ngIf="!sinlgePlacementAvailable" class="uk-margin-small-bottom">
<span class="uk-text-meta">Placement: </span>{{pluginGroup.plugin.placement}}
</div>
<!--<div class="uk-margin-small-bottom">
<span class="uk-text-meta">Order: </span>{{pluginGroup.plugin.order}}
</div>-->
<ul uk-accordion>
<li>
<a (click)="pluginGroup.openPreview = !pluginGroup.openPreview" class="uk-accordion-title">Preview</a>
<div class="uk-accordion-content">
<ng-container *ngIf="pluginGroup.openPreview">
<plugin-wrapper [pluginTemplate]="pluginGroup.template" [plugin]="pluginGroup.plugin"
[pluginObject]="pluginGroup.plugin.object" [previewInAdmin]="true"></plugin-wrapper>
</ng-container>
</div>
</li>
</ul>
</div>
</div>
<div class="uk-card-footer uk-padding-remove-vertical">
<div class="uk-grid uk-grid-small uk-flex-nowrap uk-grid-divider uk-flex-right" uk-grid>
<div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<a
class="uk-button uk-button-link uk-flex uk-flex-middle"
routerLink="./edit" [queryParams]=" { 'pageId': page._id, pluginId: pluginGroup.plugin._id, templateId:pluginGroup.template._id }"
[class.uk-disabled]="!pluginGroup.template">
<icon name="edit" [flex]="true"></icon>
<span class="uk-margin-xsmall-left"> Edit</span>
</a>
</div>
</div>
<!-- <div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<button
class="uk-button uk-button-link uk-flex uk-flex-middle"
(click)="edit(pluginGroup.plugin, pluginGroup.template, placement, i)"
[class.uk-disabled]="!pluginGroup.template">
<icon name="edit" [flex]="true"></icon>
<span class="uk-margin-xsmall-left"> Edit</span>
</button>
</div>
</div>-->
<div *ngIf="pluginGroup.plugin.custom && pluginGroup.template.custom">
<div class="uk-padding-small uk-padding-remove-horizontal">
<button
class="uk-button uk-button-link uk-flex uk-flex-middle uk-text-danger"
(click)="promtToDelete(i, placement.value)">
<icon name="delete" [flex]="true"></icon>
<span class="uk-margin-xsmall-left">Delete</span>
</button>
</div>
</div>
<!-- Maybe change delete to reset to default values ? -->
<!--<div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<button class="uk-button uk-button-link uk-flex uk-flex-middle"
(click)="confirmDelete(check.plugin._id)">
<icon name="delete" [flex]="true"></icon>
<span class="uk-margin-xsmall-left"> Delete</span>
</button>
</div>
</div>-->
<div *ngIf="i >0">
<div class="uk-padding-small uk-padding-remove-horizontal">
<button
class="uk-button uk-button-link uk-flex uk-flex-middle" [class.uk-disabled]="filterActive" [title]="filterActive?'Move is disabled when plugins are filtered':''"
(click)="swap(i, i-1, placement.value)">
<icon name="arrow_upward" [flex]="true"></icon>
<span class="uk-margin-xsmall-left"> Up</span>
</button>
</div>
</div>
<div *ngIf="i < pluginsByPlacement.get(placement.value).length -1 ">
<div class="uk-padding-small uk-padding-remove-horizontal">
<button
class="uk-button uk-button-link uk-flex uk-flex-middle" [class.uk-disabled]="filterActive" [title]="filterActive?'Move is disabled when plugins are filtered':''"
(click)="swap(i+1, i, placement.value)">
<icon name="arrow_downward" [flex]="true"></icon>
<span class="uk-margin-xsmall-left">Down</span>
</button>
</div>
</div>
<div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<mat-slide-toggle [checked]="pluginGroup.plugin.active"
(change)="($event.source.checked = pluginGroup.plugin.active);togglePlugin(!pluginGroup.plugin.active,pluginGroup.plugin._id,i, placement.value)"
>
<span class="uk-text-small">Enable</span>
</mat-slide-toggle>
</div>
</div>
</div>
</div>
</div>
</ng-container>
</ng-container>
</div>
</ng-container>
</ng-container>
</ng-container>
</div>
</div>
<!--</div>-->
<modal-alert #deleteModal [overflowBody]="false" (alertOutput)="confirmDelete()"
classTitle="uk-background-primary uk-light"></modal-alert>

View File

@ -0,0 +1,373 @@
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {HelpContentService} from "../../services/help-content.service";
import {FormArray, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, ValidatorFn} from "@angular/forms";
import {Page} from "../../utils/entities/adminTool/page";
import {EnvProperties} from '../../utils/properties/env-properties';
import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {PortalUtils} from "../portal/portalHelper";
import {Option} from "../../sharedComponents/input/input.component";
import {Title} from "@angular/platform-browser";
import {ClearCacheService} from "../../services/clear-cache.service";
import {NotificationHandler} from "../../utils/notification-handler";
import {PluginsService} from "../../services/plugins.service";
import {Plugin} from "../../utils/entities/adminTool/plugin";
import {StringUtils} from "../../utils/string-utils.class";
import {Portal} from "../../utils/entities/adminTool/portal";
import {PluginTemplate} from "../../utils/entities/adminTool/pluginTemplate";
import {PluginUtils} from "./utils/pluginUtils";
import {CommunityService} from "../../connect/community/community.service";
import {CommunityInfo} from "../../connect/community/communityInfo";
import {AlertModal} from "../../utils/modal/alert";
@Component({
selector: 'plugins',
templateUrl: './plugins.component.html',
})
export class PluginsComponent implements OnInit {
public pluginsByPlacement: Map<string, { plugin: Plugin, template: PluginTemplate, openPreview: boolean }[]> = new Map();
public plugins: Plugin[] = [];
public pluginTemplates: PluginTemplate[] = [];
public selectedTemplate: PluginTemplate = null;
public selectedPlugin: Plugin = null;
// public editView = false;
// public selectTemplateView = false;
// public templateForm: UntypedFormGroup;
// public pagesCtrl: UntypedFormArray;
urlValidator: ValidatorFn = StringUtils.urlValidator;
private searchText: RegExp = new RegExp('');
public keyword: string = "";
public properties: EnvProperties = properties;
// public formPages: Page[] = [];
public showLoading: boolean = true;
private subscriptions: any[] = [];
public allPages: Option[] = [];
public pluginUtils = new PluginUtils();
selectedCommunityPid = null;
public portalUtils: PortalUtils = new PortalUtils();
private index: number;
public portal: string;
public selectedPageId: string;
public community: Portal;
public page: Page;
public templateView = false;
// public templateCode: string = null;
// public template;
public selectedPlacementView = "all";
public selectedPluginIndex = null;
public sinlgePlacementAvailable = false;
communityInfo: CommunityInfo = null;
// editSubmenuOpen = false;
filterActive = false;
@ViewChild('deleteModal') deleteModal: AlertModal;
constructor(private element: ElementRef, private route: ActivatedRoute, private _router: Router,
private communityService: CommunityService,
private title: Title, private _helpContentService: HelpContentService,
private _pluginsService: PluginsService, private _fb: UntypedFormBuilder,
private _clearCacheService: ClearCacheService) {
}
ngOnInit() {
this.title.setTitle('Administrator Dashboard | Plugins');
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(
community => {
this.communityInfo = community;
}));
this.subscriptions.push(this.route.params.subscribe(params => {
this.portal = (this.route.snapshot.data.portal) ? this.route.snapshot.data.portal : this.route.snapshot.params[this.route.snapshot.data.param];
this.selectedCommunityPid = params.community;
this.subscriptions.push(this.route.queryParams.subscribe(params => {
HelperFunctions.scroll();
this.selectedPageId = params['pageId'];
if (this.portal && this.selectedPageId) {
this.getPage(this.selectedPageId);
}
if (!this.selectedPageId && !this.templateView) {
this._router.navigate(['../pages'], {relativeTo: this.route});
}
}));
}));
}
ngOnDestroy(): void {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
} else if (value instanceof Function) {
value();
}
});
}
getTemplateById(id) {
for (let template of this.pluginTemplates) {
if (template._id == id) {
return template;
}
}
return null;
}
getPage(pageId: string) {
this.showLoading = true;
this.subscriptions.push(this._helpContentService.getPageByPortal(pageId, this.properties.adminToolsAPIURL, this.portal).subscribe(
page => {
if (this.properties.adminToolsPortalType != page.portalType) {
this._router.navigate(['./pageContents']);
} else {
this.page = page;
this.getPagePlugins();
}
},
error => this.handleError('System error retrieving page', error)));
}
getPagePlugins() {
this.showLoading = true;
this.subscriptions.push(this._pluginsService.getPluginTemplatesByPage(this.properties.adminToolsAPIURL, this.selectedCommunityPid, this.selectedPageId).subscribe(
templates => {
this.pluginTemplates = templates;
this.subscriptions.push(this._pluginsService.getPluginsByPage(this.properties.adminToolsAPIURL, this.selectedCommunityPid, this.selectedPageId).subscribe(
plugins => {
this.plugins = plugins;
this.pluginsByPlacement = new Map();
for (let pos of this.pluginUtils.placementsOptions) {
this.pluginsByPlacement.set(pos.value, []);
}
let self = this;
this.pluginTemplates.forEach(_ => {
let plugin: Plugin = null;
if(!_.custom) {
for (let pl of plugins) {
if (pl.templateId == _._id) {
plugin = pl;
}
}
if (!plugin) {
plugin = new Plugin(this.selectedPageId, this.selectedCommunityPid, _);
this.plugins.push(plugin);
}
if (plugin) {
plugin.object = PluginUtils.initializeObjectAndCompare(_.code, plugin.object)
this.pluginsByPlacement.get(plugin.placement).push({plugin: plugin, template: _, openPreview: false});
}
}
});
//add custom plugins in the list
this.plugins.forEach(_ => {
if(_.custom){
let customTemplate = null;
this.pluginTemplates.forEach(template => {
if (_.templateId == template._id) {
customTemplate = template;
}
});
if(customTemplate && customTemplate.custom){
this.pluginsByPlacement.get(customTemplate.placement).push({plugin: _, template: customTemplate, openPreview: false});
}
}
});
let availablePlacements = [];
for (let placement of this.pluginUtils.placementsOptions) {
if (this.pluginsByPlacement.get(placement.value).length > 0) {
availablePlacements.push(placement.value);
}
this.pluginsByPlacement.get(placement.value).sort(function (a, b) {
return a.plugin.order - b.plugin.order;
})
}
if (availablePlacements.length == 1) {
this.selectedPlacementView = availablePlacements[0];
this.sinlgePlacementAvailable = true
}
this.showLoading = false;
},
error => this.handleError('System error retrieving plugins', error)));
},
error => this.handleError('System error retrieving templates', error)));
}
public savePlugin(plugin, update, index) {
this.subscriptions.push(this._pluginsService.savePlugin(plugin, this.properties.adminToolsAPIURL, this.selectedCommunityPid).subscribe(
saved => {
this.savedSuccessfully(saved, update, index);
this.selectedTemplate = null;
this.selectedPlugin = null;
this.clearCache();
if (plugin.custom) {
this._router.navigate(["./edit"], {
queryParams: {
'pageId': this.selectedPageId,
pluginId: saved._id,
templateId: saved.templateId
}, relativeTo: this.route
})
}
},
error => this.handleUpdateError("System error creating template", error)
));
}
public savedSuccessfully(plugin: Plugin, update: boolean, index) {
console.log(plugin.placement, index, update)
if (update) {
this.pluginsByPlacement.get(plugin.placement)[index].plugin = plugin;
} else {
this.plugins.push(plugin);
}
this.showLoading = false;
}
public filterPlugins(plugin: Plugin, template: PluginTemplate): boolean {
let values = [];
for (let key of this.getKeys(plugin.settingsValues)) {
values.push(plugin.settingsValues[key]);
}
return this.searchText.toString() == '' || (plugin.templateCode + ' ' + values.join(' ') + (template ? (template.name + ' ' + template.description) : '')).match(this.searchText) != null;
}
handleUpdateError(message: string, error = null) {
if (error) {
console.log('Server responded: ' + error);
}
NotificationHandler.rise(message, 'danger');
this.showLoading = false;
}
handleError(message: string, error = null) {
if (error) {
console.log('Server responded: ' + error);
}
NotificationHandler.rise(message, 'danger');
this.showLoading = false;
}
getPages() {
this.showLoading = true;
this.subscriptions.push(this._helpContentService.getAllPages(this.properties.adminToolsAPIURL).subscribe(
pages => {
this.allPages = [];
pages.forEach(page => {
this.allPages.push({
label: page.name + " [" + page.portalType + "]",
value: page
});
});
this.showLoading = false;
},
error => this.handleError('System error retrieving pages', error)
));
}
attributeTypeChanged(form) {
let type = form.get("value").get("type");
form.get("value").setValue("");
if (type == "boolean") {
form.get("value").setValue(false);
}
}
getKeys(obj) {
return obj ? Object.keys(obj) : [];
}
public togglePlugin(status: boolean, id: string, i, placement) {
this.index = i;
this.selectedTemplate = this.pluginsByPlacement.get(placement)[i].template;
if (id) {
this.subscriptions.push(this._pluginsService.togglePlugin(id, status, this.properties.adminToolsAPIURL, this.selectedCommunityPid).subscribe(
() => {
this.pluginsByPlacement.get(placement)[i].plugin.active = status;
this.clearCache();
},
error => this.handleUpdateError('System error changing the status of Plugin', error)
));
} else {
let plugin = this.pluginsByPlacement.get(placement)[i].plugin;
plugin.active = status;
this.savePlugin(plugin, true, i);
}
}
public swap(pluginToMoveUp, pluginToMoveDown, placement) {
this.showLoading = true;
let moveUpGroup = this.pluginsByPlacement.get(placement)[pluginToMoveUp];
let moveDownGroup = this.pluginsByPlacement.get(placement)[pluginToMoveDown];
this.pluginsByPlacement.get(placement)[pluginToMoveUp] = moveDownGroup;
this.pluginsByPlacement.get(placement)[pluginToMoveDown] = moveUpGroup;
this.move(moveUpGroup.plugin, true, pluginToMoveDown, placement);
this.move(moveDownGroup.plugin, false, pluginToMoveUp, placement);
this.showLoading = false;
}
public move(plugin: Plugin, up: boolean, index, placement) {
if (plugin._id) {
this.subscriptions.push(this._pluginsService.updatePluginOrder(plugin, this.properties.adminToolsAPIURL, up ? -1 : 1, this.selectedCommunityPid).subscribe(
saved => {
this.pluginsByPlacement.get(placement)[index].plugin = saved;
this.clearCache();
},
error => this.handleUpdateError("System error saving plugin", error)
));
} else {
plugin.order = plugin.order + (up ? -1 : 1)
this.savePlugin(plugin, true, index);
}
}
clearCache() {
// this._clearCacheService.clearCacheInRoute(null, this.selectedCommunityPid, this.getPageById(this.selectedPageId).route)
this._clearCacheService.purgeBrowserCache(null, this.selectedCommunityPid)
}
addNewCustomPlugin(template: PluginTemplate) {
let plugin = new Plugin(this.page._id, this.selectedCommunityPid, template);
plugin.order = this.pluginsByPlacement.get(this.selectedPlacementView).length;
plugin.object = PluginUtils.initializeObjectAndCompare(template.code, null);
plugin.custom = true;
this.savePlugin(plugin, false, this.pluginsByPlacement.get(this.selectedPlacementView).length);
}
promtToDelete(i, placement) {
this.selectedPlugin = this.pluginsByPlacement.get(placement)[i].plugin;
this.selectedPlacementView = placement;
this.selectedPluginIndex = i;
this.deleteModal.alertTitle = 'Delete Confirmation';
this.deleteModal.message = 'Are you sure you want to delete the selected plugin?';
this.deleteModal.okButtonText = 'Yes';
this.deleteModal.open();
}
confirmDelete() {
this.showLoading = true;
this.subscriptions.push(this._pluginsService.deletePlugin(this.selectedPlugin._id, this.properties.adminToolsAPIURL).subscribe(
deleted => {
this.pluginsByPlacement.get(this.selectedPlacementView).splice(this.selectedPluginIndex, 1);
this.clearCache();
},
error => this.handleUpdateError("System error creating template", error)
));
this.showLoading = false;
}
}

View File

@ -0,0 +1,43 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {AlertModalModule} from '../../utils/modal/alertModal.module';
import {PluginsComponent} from './plugins.component';
import {AdminToolServiceModule} from "../../services/adminToolService.module";
import {InputModule} from "../../sharedComponents/input/input.module";
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import { MatCheckboxModule } from "@angular/material/checkbox";
import { MatFormFieldModule } from "@angular/material/form-field";
import {MatChipsModule} from '@angular/material/chips';
import {AdminTabsModule} from "../sharedComponents/admin-tabs/admin-tabs.module";
import {PageContentModule} from "../sharedComponents/page-content/page-content.module";
import {PluginsRoutingModule} from "./plugins-routing.module";
import {SearchInputModule} from "../../sharedComponents/search-input/search-input.module";
import {IconsModule} from "../../utils/icons/icons.module";
import {LoadingModule} from "../../utils/loading/loading.module";
import {PluginsService} from "../../services/plugins.service";
import {CKEditorModule} from "ng2-ckeditor";
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
import {PluginWrapperModule} from "./wrapper/plugin-wrapper.module";
import {SideBarModule} from "../sharedComponents/sidebar/sideBar.module";
import {PluginEditWrapperModule} from "./wrapper/plugin-edit-wrapper.module";
import {TransitionGroupModule} from "../../utils/transition-group/transition-group.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule,
AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, MatAutocompleteModule, MatFormFieldModule, MatChipsModule,
MatCheckboxModule, AdminTabsModule, PageContentModule, PluginsRoutingModule, SearchInputModule, IconsModule, LoadingModule, CKEditorModule,
MatSlideToggleModule, PluginWrapperModule, SideBarModule, PluginEditWrapperModule, TransitionGroupModule
],
providers:[PluginsService],
declarations: [PluginsComponent],
exports: [PluginsComponent]
})
export class PluginsModule {}

View File

@ -0,0 +1,40 @@
/*
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {AlertModalModule} from '../../utils/modal/alertModal.module';
import {PluginsComponent} from './plugins.component';
import {AdminToolServiceModule} from "../../services/adminToolService.module";
import {InputModule} from "../../sharedComponents/input/input.module";
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import { MatCheckboxModule } from "@angular/material/checkbox";
import { MatFormFieldModule } from "@angular/material/form-field";
import {MatChipsModule} from '@angular/material/chips';
import {AdminTabsModule} from "../sharedComponents/admin-tabs/admin-tabs.module";
import {PageContentModule} from "../sharedComponents/page-content/page-content.module";
import {PluginsRoutingModule} from "./plugins-routing.module";
import {SearchInputModule} from "../../sharedComponents/search-input/search-input.module";
import {IconsModule} from "../../utils/icons/icons.module";
import {LoadingModule} from "../../utils/loading/loading.module";
import {PluginsService} from "../../services/plugins.service";
import {CKEditorModule} from "ng2-ckeditor";
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule,
AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, MatAutocompleteModule, MatFormFieldModule, MatChipsModule,
MatCheckboxModule, AdminTabsModule, PageContentModule, SearchInputModule, IconsModule, LoadingModule, CKEditorModule,
MatSlideToggleModule
],
providers:[PluginsService],
declarations: [PluginsComponent],
exports: [PluginsComponent]
})
export class PluginsComponentModule {}
*/

View File

@ -0,0 +1,13 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {PluginTemplatesComponent} from "./pluginTemplates.component";
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', component: PluginTemplatesComponent}
])
]
})
export class PluginTemplatesRoutingModule { }

View File

@ -0,0 +1,242 @@
<div page-content>
<div header>
<admin-tabs tab="template"></admin-tabs>
<div *ngIf="page" class="uk-width-expand">
<a routerLink="../pages" class="uk-flex uk-flex-middle uk-h5 uk-link-reset">
<span class="uk-margin-right">
<icon name="west" ratio="1.7" [flex]="true"></icon>
</span>
<h1 class="uk-h5 uk-margin-remove">{{page.name}}</h1>
</a>
</div>
<ul *ngIf="page" class="uk-subnav uk-subnav-pill uk-margin-medium-top">
<li [class.uk-active]="filterForm.get('position').value === 'all'" class="uk-margin-small-bottom"><a
(click)="filterForm.get('position').setValue('all')"><span
class="title">All placements</span></a></li>
<li *ngFor="let position of pluginUtils.placementsOptions; let i=index"
[class.uk-active]="filterForm.get('position').value === position.value" class="uk-margin-small-bottom"><a
(click)="filterForm.get('position').setValue(position.value)"><span
class="title">{{position.label}}</span></a></li>
</ul>
</div>
<div actions>
<div class="uk-section-xsmall">
<div class="uk-flex uk-flex-right@m uk-flex-center uk-flex-wrap uk-flex-middle uk-grid" uk-grid>
<!-- <div search-input [disabled]="showLoading" [expandable]="true" [searchControl]="filterForm.get('keyword')" searchInputClass="outer" placeholder="Search class" class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1"></div>-->
<div>
<button class="uk-button uk-button-default uk-flex uk-flex-middle" (click)="newPlugin()"
[disabled]="showLoading" [class.uk-disabled]="showLoading">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">Add plugin template</span>
</button>
</div>
</div>
</div>
</div>
<div inner>
<div class="uk-section uk-section-small uk-position-relative" style="min-height: 60vh">
<div *ngIf="showLoading" class="uk-position-center">
<loading></loading>
</div>
<ng-container *ngIf="!showLoading">
<!--<div *ngIf="checkboxes.length == 0"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div>No templates found</div>
</div>-->
<div class="uk-grid uk-child-width-1-1">
<ng-container *ngFor="let placement of pluginUtils.placementsOptions">
<ng-container
*ngIf="filterForm.get('position').value == placement.value || filterForm.get('position').value == 'all'">
<div
*ngIf="templatesByPlacement.get(placement.value) && templatesByPlacement.get(placement.value).length >0 && page"
class="uk-heading-divider uk-h6 uk-margin-left uk-padding-remove-left uk-text-capitalize ">{{placement.value}}</div>
<div *ngFor="let template of templatesByPlacement.get(placement.value) ; let i=index">
<div class="uk-card uk-card-default uk-margin-bottom uk-animation-fade" >
<div class="uk-card-body uk-flex">
<div class="uk-width-expand uk-text-small">
<h6>{{template.name}}</h6>
<div class="uk-margin-small-bottom">
<span class="uk-label uk-padding-xsmall uk-text-capitalize"
[class.uk-label-success]="template.plan =='Standard'"
[class.uk-label-danger]="template.plan !='Standard'">Plan: {{template.plan}} </span>
<span *ngIf="template.portalSpecific && template.portalSpecific.length > 0"
class="uk-label uk-label-primary uk-padding-xsmall uk-text-capitalize uk-margin-left">Communities: {{template.portalSpecific.join(', ')}} </span>
<span *ngIf="template.defaultIsActive"
class="uk-label uk-label-success uk-padding-xsmall uk-text-capitalize uk-margin-left">Default status: Active </span>
</div>
<div class="uk-margin-small-bottom">
{{template.description}}
</div>
<div class="uk-margin-small-bottom">
<span class="uk-text-meta">Page: </span>{{getPageAsString(template.page)}} -
<span class="uk-text-meta">Placement: </span>{{template.placement}} -
<span class="uk-text-meta">Order: </span>{{template.order}}
</div>
<div class="uk-margin-small-bottom">
<span class="uk-text-meta">Portal type: </span>{{template.portalType}}
</div>
<ul uk-accordion>
<li>
<a class="uk-accordion-title">Preview</a>
<div class="uk-accordion-content">
<plugin-wrapper [pluginTemplate]="template"
[pluginObject]="template.object"></plugin-wrapper>
</div>
</li>
</ul>
</div>
</div>
<div class="uk-card-footer uk-padding-remove-vertical">
<div class="uk-grid uk-grid-small uk-flex-nowrap uk-grid-divider uk-flex-right" uk-grid>
<ng-container>
<div *ngIf="i>0">
<div class="uk-padding-small uk-padding-remove-horizontal">
<button
class="uk-button uk-button-link uk-flex uk-flex-middle"
(click)="swap(i, i-1, template.placement)">
<icon name="arrow_upward" [flex]="true"></icon>
<span class="uk-margin-xsmall-left"> Up</span>
</button>
</div>
</div>
<div *ngIf="i < templatesByPlacement.get(placement.value).length -1 ">
<div class="uk-padding-small uk-padding-remove-horizontal">
<button
class="uk-button uk-button-link uk-flex uk-flex-middle"
(click)="swap(i+1, i, template.placement)">
<icon name="arrow_downward" [flex]="true"></icon>
<span class="uk-margin-xsmall-left"> Down</span>
</button>
</div>
</div>
</ng-container>
<div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<button
class="uk-button uk-button-link uk-flex uk-flex-middle" (click)="edit(template)">
<icon name="edit" [flex]="true"></icon>
<span class="uk-margin-xsmall-left"> Edit</span>
</button>
</div>
</div>
<div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<button class="uk-button uk-button-link uk-flex uk-flex-middle"
(click)="confirmDelete(template)">
<icon name="delete" [flex]="true"></icon>
<span class="uk-margin-xsmall-left"> Delete</span>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- </div>-->
</div>
<!-- </div>-->
</ng-container>
</ng-container>
</div>
</ng-container>
</div>
</div>
</div>
<modal-alert #editModal (alertOutput)="saveConfirmed($event)" [large]="true"
[okDisabled]="templateForm && (templateForm.invalid || !templateForm.dirty)"
classTitle="uk-background-primary uk-light">
<form *ngIf="templateForm" [formGroup]="templateForm" class="uk-grid " uk-grid>
<div class="uk-width-1-3 " *ngIf="templateForm.getRawValue()['_id']">
<div class="uk-card uk-card-default uk-padding-small">
<div *ngIf="!editSubmenuOpen" class="uk-text-muted uk-text-bold uk-text-center uk-margin-bottom">Plugin
options
</div>
<plugin-wrapper-form [pluginTemplate]="templateForm.getRawValue()"
[pluginObject]="selectedTemplate.object"
(changed)="pluginFieldChanged($event)" [editTemplate]="true" [editSubmenuOpen]="editSubmenuOpen"></plugin-wrapper-form>
</div>
</div>
<div class="uk-grid uk-width-expand uk-child-width-1-2" uk-grid>
<div input [formInput]="templateForm.get('name')" placeholder="Template Name"></div>
<div input [formInput]="templateForm.get('code')" placeholder="Template Code"
[options]="pluginUtils.availablePluginCodes" type="select"></div>
<div class="uk-width-1-1" input [formInput]="templateForm.get('description')" placeholder="Description"
type="textarea"></div>
<div input [formInput]="templateForm.get('plan')" placeholder="Plan" [options]="pluginUtils.planOptions"
type="select"></div>
<div input [formInput]="templateForm.get('image')" placeholder="Image"></div>
<div input [formInput]="templateForm.get('portalType')" placeholder="Portal Type"
[options]="portalUtils.portalTypes" type="select"></div>
<div input [formInput]="templateForm.get('placement')" placeholder="Placement"
[options]="pluginUtils.placementsOptions" type="select"></div>
<div input [formInput]="templateForm.get('custom')" placeholder="Custom"
[options]="pluginUtils.customOptions" type="select"></div>
<div *ngIf="!templateForm.get('portalType').value" input [formInput]="templateForm.get('page')" placeholder="Page"
[options]="allPages" type="select"></div>
<div *ngIf="templateForm.get('portalType').value" input [formInput]="templateForm.get('page')" placeholder="Page"
[options]="allPagesByPortal.get(templateForm.get('portalType').value)" type="select"></div>
<div input [formInput]="templateForm.get('portalSpecific')" placeholder="Available to communities"
hint="community ids, comma seperated, no spaces"></div>
<div input [formInput]="templateForm.get('order')" placeholder="Order"></div>
<div>Default Status
<mat-slide-toggle [checked]="templateForm.get('defaultIsActive').value"
(change)="templateForm.get('defaultIsActive').setValue($event.checked); templateForm.markAsDirty()"></mat-slide-toggle>
</div>
<!--<plugin-wrapper *ngIf="selectedTemplate "
[pluginTemplate]="this.templateForm.getRawValue()" [pluginObject]="this.templateForm.getRawValue().object" class="uk-width-1-1" ></plugin-wrapper>-->
<div *ngFor="let attrForm of attrFormArray.controls; let i=index" class="uk-width-1-1 uk-grid uk-child-width-1-2"
uk-grid>
<div class="uk-heading-divider uk-text-small uk-width-1-1 uk-margin-bottom uk-text-meta">
<div class="uk-grid">
<div>Setting #{{i + 1}}</div>
<div class=" uk-width-expand uk-text-right ">
<a class=" " (click)="removeAttr(i)">Remove</a>
</div>
</div>
</div>
<div input [formInput]="attrForm.get('key')" placeholder="Key"></div>
<div input [formInput]="attrForm.get('name')" placeholder="Name"></div>
<div input [formInput]="attrForm.get('type')" placeholder="Type" [options]="pluginUtils.attrTypeOptions"
type="select" (valueChange)="attributeTypeChanged(attrForm)"></div>
<div *ngIf="attrForm.get('type').value == 'text'" input [formInput]="attrForm.get('value')"
placeholder="Default value" [type]="attrForm.get('type').value"></div>
<div *ngIf="attrForm.get('type').value == 'URL'" input [formInput]="attrForm.get('value')"
placeholder="Default value" [type]="attrForm.get('type').value" [validators]="urlValidator"></div>
<div *ngIf="attrForm.get('type').value == 'boolean'" input [formInput]="attrForm.get('value')"
placeholder="Default value" type="select"
[options]="[{label: 'yes', value:true}, {label: 'no', value:false}]"></div>
<div *ngIf="attrForm.get('type').value == 'HTML'" class="uk-width-1-1">
<ckeditor [readonly]="false"
debounce="500"
[formControl]="attrForm.get('value')"
[config]="{ extraAllowedContent: '* [uk-*](*) ; span', disallowedContent: 'script; *[on*]',
removeButtons: 'Save,NewPage,DocProps,Preview,Print,' +
'Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,' +
'CreateDiv,Flash,PageBreak,' +
'Subscript,Superscript,Anchor,Smiley,Iframe,Styles,Font,About,Language',
extraPlugins: 'divarea'}">
</ckeditor>
</div>
</div>
<hr class="uk-width-1-1">
<div class="uk-width-1-1 uk-text-center ">
<a (click)="addNewAttr()">Add settings</a>
</div>
<div *ngIf="templateForm.getRawValue()['_id']" class="uk-width-1-1">
<hr class="uk-width-1-1">
<div class="uk-text-muted uk-text-bold uk-width-1-1 uk-text-center">Plugin preview</div>
<plugin-wrapper [pluginTemplate]="templateForm.getRawValue()"
[pluginObject]="selectedTemplate.object"></plugin-wrapper>
</div>
</div>
</form>
</modal-alert>
<modal-alert #deleteModal (alertOutput)="confirmedDelete()" classTitle="uk-background-primary uk-light"></modal-alert>

View File

@ -0,0 +1,382 @@
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {HelpContentService} from "../../../services/help-content.service";
import {FormArray, FormGroup, UntypedFormBuilder, UntypedFormGroup, ValidatorFn, Validators} from "@angular/forms";
import {Page} from "../../../utils/entities/adminTool/page";
import {EnvProperties} from '../../../utils/properties/env-properties';
import {HelperFunctions} from "../../../utils/HelperFunctions.class";
import {Subscriber} from "rxjs";
import {properties} from "../../../../../environments/environment";
import {PortalUtils} from "../../portal/portalHelper";
import {AlertModal} from "../../../utils/modal/alert";
import {Option} from "../../../sharedComponents/input/input.component";
import {Title} from "@angular/platform-browser";
import {ClearCacheService} from "../../../services/clear-cache.service";
import {NotificationHandler} from "../../../utils/notification-handler";
import {PluginsService} from "../../../services/plugins.service";
import {PluginTemplate} from "../../../utils/entities/adminTool/pluginTemplate";
import {StringUtils} from "../../../utils/string-utils.class";
import {PluginUtils} from "../utils/pluginUtils";
import {PluginEditEvent} from "../utils/base-plugin.form.component";
@Component({
selector: 'plugin-templates',
templateUrl: './pluginTemplates.component.html',
})
export class PluginTemplatesComponent implements OnInit {
@ViewChild('editModal') editModal: AlertModal;
@ViewChild('deleteModal') deleteModal: AlertModal;
public templatesByPlacement: Map<string,PluginTemplate[]> = new Map();
public templateForm: UntypedFormGroup;
urlValidator: ValidatorFn = StringUtils.urlValidator;
private searchText: RegExp = new RegExp('');
public keyword: string = "";
public properties: EnvProperties = properties;
public formPages: Page[] = [];
public showLoading: boolean = true;
public filterForm: UntypedFormGroup;
private subscriptions: any[] = [];
public allPages: Option[] = [];
public allPagesByPortal: Map<string, Option[]> = new Map();
public pluginUtils = new PluginUtils();
public portalUtils: PortalUtils = new PortalUtils();
private selectedTemplate: PluginTemplate;
public selectedPageId: string;
public selectedPortalPid: string;
public page: Page;
editSubmenuOpen = false;
constructor(private element: ElementRef, private route: ActivatedRoute, private _router: Router,
private title: Title, private _helpContentService: HelpContentService,
private _pluginsService: PluginsService, private _fb: UntypedFormBuilder,
private _clearCacheService: ClearCacheService) {
}
ngOnInit() {
this.title.setTitle('Administrator Dashboard | Classes');
this.filterForm = this._fb.group({
keyword: [''],
position: ['all', Validators.required]
});
this.subscriptions.push(this.filterForm.get('keyword').valueChanges.subscribe(value => {
this.searchText = new RegExp(value, 'i');
}));
this.subscriptions.push(this.route.queryParams.subscribe(params => {
HelperFunctions.scroll();
this.selectedPageId = params['pageId'];
this.selectedPortalPid = params['portalPid'];
if (this.selectedPageId) {
this.getPage(this.selectedPageId);
this.getTemplates(this.selectedPageId);
} else {
this.getPages();
this.getTemplates();
}
}));
}
ngOnDestroy(): void {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
} else if (value instanceof Function) {
value();
}
});
}
getPage(pageId: string) {
this.showLoading = true;
this.subscriptions.push(this._helpContentService.getPageById(pageId, this.properties.adminToolsAPIURL).subscribe(
page => {
this.page = page;
this.allPages = [];
this.allPagesByPortal = new Map();
let option = {
label: page.name + " [" + page.portalType + "]",
value: page
};
this.allPages.push(option);
this.allPagesByPortal.set(page.portalType, [])
this.allPagesByPortal.get(page.portalType).push(option)
},
error => this.handleError('System error retrieving page', error)));
}
getTemplates(pageId = null) {
this.showLoading = true;
this.subscriptions.push(this._pluginsService.getPluginTemplates(this.properties.adminToolsAPIURL, pageId).subscribe(
templates => {
for(let pos of this.pluginUtils.placementsOptions){
this.templatesByPlacement.set(pos.value,[]);
}
for(let template of templates){
template.object = PluginUtils.initializeObjectAndCompare(template.code,template.object)
this.templatesByPlacement.get(template.placement).push(template);
}
let self = this;
this.showLoading = false;
},
error => this.handleError('System error retrieving classes', error)));
}
private deleteFromArray(template:PluginTemplate): void {
let i = this.templatesByPlacement.get(template.placement).findIndex(_ => _._id == template._id);
this.templatesByPlacement.get(template.placement).splice(i, 1);
}
public confirmDelete(template:PluginTemplate) {
this.selectedTemplate = template;
this.confirmModalOpen();
}
private confirmModalOpen() {
this.deleteModal.alertTitle = "Delete Confirmation";
this.deleteModal.message = "Are you sure you want to delete the selected template(s)?";
this.deleteModal.okButtonText = "Yes";
this.deleteModal.open();
}
public confirmedDelete() {
this.showLoading = true;
this.subscriptions.push(this._pluginsService.deletePluginTemplate(this.selectedTemplate._id, this.properties.adminToolsAPIURL).subscribe(
_ => {
this.deleteFromArray(this.selectedTemplate);
NotificationHandler.rise('Template have been <b>successfully deleted</b>');
this.showLoading = false;
// this._clearCacheService.clearCache("Template id deleted");
},
error => this.handleUpdateError('System error deleting the selected Template', error)
));
}
public edit(pluginTemplate) {
this.selectedTemplate = JSON.parse(JSON.stringify(pluginTemplate)); // deep copy object with nested objects
this.templateForm = this._fb.group({
_id: this._fb.control(pluginTemplate._id),
name: this._fb.control(pluginTemplate.name),
page: this._fb.control(this.getPageById(pluginTemplate.page)),
custom: this._fb.control(pluginTemplate.custom),
portalType: this._fb.control(pluginTemplate.portalType, Validators.required),
code: this._fb.control(pluginTemplate.code, Validators.required),
description: this._fb.control(pluginTemplate.description),
plan: this._fb.control(pluginTemplate.plan, Validators.required),
placement: this._fb.control(pluginTemplate.placement, Validators.required),
order: this._fb.control(pluginTemplate.order),
portalSpecific: this._fb.control(pluginTemplate.portalSpecific?pluginTemplate.portalSpecific.join(','):''),
defaultIsActive: this._fb.control(pluginTemplate.defaultIsActive),
settings: this._fb.array([]),
});
this.templateForm.get('portalType').disable();
if (pluginTemplate.settings) {
for (let attrKey of Object.keys(pluginTemplate.settings)) {
(this.templateForm.get("settings") as FormArray).push(this._fb.group({
key: this._fb.control(attrKey, Validators.required),
name: this._fb.control(pluginTemplate.settings[attrKey].name, Validators.required),
type: this._fb.control(pluginTemplate.settings[attrKey].type, Validators.required),
value: this._fb.control(pluginTemplate.settings[attrKey].value)
}));
}
}
this.modalOpen("Edit Template", "Save Changes");
}
public newPlugin() {
this.selectedTemplate = null;
if (this.templateForm) {
this.templateForm.get('portalType').enable();
}
this.templateForm = this._fb.group({
_id: this._fb.control(null),
name: this._fb.control(''),
code: this._fb.control('', Validators.required),
plan: this._fb.control('Standard', Validators.required),
description: this._fb.control(''),
page: this._fb.control(this.page?this.getPageById(this.page):'', Validators.required),
portalType: this._fb.control('community', Validators.required),
placement: this._fb.control('top', Validators.required),
order: this._fb.control(''),
custom: this._fb.control(false),
portalSpecific: this._fb.control(''),
defaultIsActive: this._fb.control(false),
settings: this._fb.array([]),
object: this._fb.control({})
});
// this.addNewAttr();
this.modalOpen("Create template", "Create");
}
private modalOpen(title: string, yesBtn: string) {
this.editModal.okButtonLeft = false;
this.editModal.alertTitle = title;
this.editModal.okButtonText = yesBtn;
this.editModal.open();
}
public swap(templateToMoveUp, templateToMoveDown, placement) {
let moveUpTemplate = this.templatesByPlacement.get(placement)[templateToMoveUp];
let moveDownTemplate = this.templatesByPlacement.get(placement)[templateToMoveDown];
this.templatesByPlacement.get(placement)[templateToMoveUp] = moveDownTemplate;
this.templatesByPlacement.get(placement)[templateToMoveDown] = moveUpTemplate;
this.move(moveUpTemplate, true, templateToMoveDown, placement);
this.move(moveDownTemplate, false, templateToMoveUp, placement);
}
public move(template: PluginTemplate, up: boolean, index, placement) {
this.subscriptions.push(this._pluginsService.updatePluginTemplateOrder(template, this.properties.adminToolsAPIURL, up ? -1 : 1).subscribe(
saved => {
this.templatesByPlacement.get(placement)[index] = saved;
},
error => this.handleUpdateError("System error creating template", error)
));
}
public saveConfirmed(data: any) {
this.showLoading = true;
let template: PluginTemplate = <PluginTemplate>this.templateForm.getRawValue();
template.page = this.templateForm.getRawValue().page._id
template.portalSpecific = this.templateForm.getRawValue().portalSpecific.length > 0? this.templateForm.getRawValue().portalSpecific.split(','):[];
template.object = this.selectedTemplate?this.selectedTemplate.object:PluginUtils.initializeObjectAndCompare(template.code);
template.settings = new Map<string, { name: string; type: string; value: string }>();
this.editSubmenuOpen = false;
if(!template._id){
template.order = this.templatesByPlacement.get(template.placement).length > 0 ? this.templatesByPlacement.get(template.placement).length:0;
}
for (let attr of this.templateForm.getRawValue().settings) {
template.settings[attr.key] = {name: attr.name, type: attr.type, value: attr.value};
}
let update = template._id ? true : false;
this.subscriptions.push(this._pluginsService.savePluginTemplate(template, this.properties.adminToolsAPIURL).subscribe(
saved => {
this.selectedTemplate = saved;
this.savedSuccessfully(saved, update);
NotificationHandler.rise('Template <b>' + saved.name + '</b> has been <b>successfully' + (update ? ' updated ' : ' created ') + '</b>');
// this._clearCacheService.clearCache("Template id saved");
},
error => this.handleUpdateError("System error creating template", error)
));
}
public savedSuccessfully(template: PluginTemplate, update: boolean) {
if (update) {
let index = this.templatesByPlacement.get(this.selectedTemplate.placement).findIndex(value => value._id === template._id);
this.templatesByPlacement.get(this.selectedTemplate.placement)[index] = template;
// TODO sort
// this.templatesByPlacement.get(this.selectedTemplate.placement) = this.templatesByPlacement.get(this.selectedTemplate.placement).sort()
} else {
template.object = PluginUtils.initializeObjectAndCompare(template.code, template.object)
this.templatesByPlacement.get(this.selectedTemplate.placement).push(template);
}
this.showLoading = false;
}
public filter(plugin: PluginTemplate): boolean {
return this.searchText.toString() == '' || (plugin.name + ' ' + plugin.portalType).match(this.searchText) != null;
}
handleUpdateError(message: string, error = null) {
if (error) {
console.log('Server responded: ' + error);
}
NotificationHandler.rise(message, 'danger');
this.showLoading = false;
}
handleError(message: string, error = null) {
if (error) {
console.log('Server responded: ' + error);
}
NotificationHandler.rise(message, 'danger');
this.showLoading = false;
}
getPages() {
this.showLoading = true;
this.subscriptions.push(this._helpContentService.getAllPages(this.properties.adminToolsAPIURL).subscribe(
pages => {
this.allPages = [];
this.allPagesByPortal = new Map();
pages.forEach(page => {
let option = {
label: page.name + " [" + page.portalType + "]",
value: page
};
this.allPages.push(option);
if (!this.allPagesByPortal.has(page.portalType)) {
this.allPagesByPortal.set(page.portalType, [])
}
this.allPagesByPortal.get(page.portalType).push(option)
});
this.showLoading = false;
},
error => this.handleError('System error retrieving pages', error)
));
}
addNewAttr() {
(this.templateForm.get("settings") as FormArray).push(this._fb.group({
key: this._fb.control("", Validators.required),
name: this._fb.control("", Validators.required),
type: this._fb.control("text", Validators.required),
value: this._fb.control("")
}));
}
removeAttr(index) {
this.attrFormArray.removeAt(index);
this.attrFormArray.markAsDirty();
}
get attrFormArray() {
return this.templateForm.get("settings") as FormArray;
}
attributeTypeChanged(form) {
let type = form.get("value").get("type");
form.get("value").setValue("");
if (type == "boolean") {
form.get("value").setValue(false);
}
}
public getPageAsString(pageId): string {
return this.allPages.filter(option => option.value._id == pageId).map((option => option.value.name + " [" + option.value.portalType + "]")).join(",");
}
public getPageById(pageId) {
for (let option of this.allPages) {
if (option.value._id == pageId) {
return option.value;
}
}
return pageId;
}
pluginFieldChanged($event:PluginEditEvent){
if($event.type == "open-submenu"){
this.editSubmenuOpen = true;
return;
}
if($event.type == "close-submenu"){
this.editSubmenuOpen = false;
return;
}
this.selectedTemplate.object[$event.field]=$event.value;
this.templateForm.markAsDirty();
}
public getPagesByPortal(portal) {
return this.allPages.filter(option => option.value.portalType == portal);
}
}

View File

@ -0,0 +1,39 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {AlertModalModule} from '../../../utils/modal/alertModal.module';
import {PluginTemplatesComponent} from './pluginTemplates.component';
import {AdminToolServiceModule} from "../../../services/adminToolService.module";
import {InputModule} from "../../../sharedComponents/input/input.module";
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {MatCheckboxModule} from "@angular/material/checkbox";
import {MatFormFieldModule} from "@angular/material/form-field";
import {MatChipsModule} from '@angular/material/chips';
import {AdminTabsModule} from "../../sharedComponents/admin-tabs/admin-tabs.module";
import {PageContentModule} from "../../sharedComponents/page-content/page-content.module";
import {PluginTemplatesRoutingModule} from "./pluginTemplates-routing.module";
import {SearchInputModule} from "../../../sharedComponents/search-input/search-input.module";
import {IconsModule} from "../../../utils/icons/icons.module";
import {LoadingModule} from "../../../utils/loading/loading.module";
import {PluginsService} from "../../../services/plugins.service";
import {CKEditorModule} from "ng2-ckeditor";
import {PluginWrapperModule} from "../wrapper/plugin-wrapper.module";
import {PluginEditWrapperModule} from "../wrapper/plugin-edit-wrapper.module";
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule,
AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, MatAutocompleteModule, MatFormFieldModule, MatChipsModule,
MatCheckboxModule, AdminTabsModule, PageContentModule, PluginTemplatesRoutingModule, SearchInputModule, IconsModule, LoadingModule, CKEditorModule, PluginWrapperModule, PluginEditWrapperModule, MatSlideToggleModule
],
providers:[PluginsService],
declarations: [PluginTemplatesComponent],
exports: [PluginTemplatesComponent]
})
export class PluginTemplatesModule {}

View File

@ -0,0 +1,118 @@
import {Directive, Input, OnDestroy} from '@angular/core';
import {Plugin} from "../../../utils/entities/adminTool/plugin";
import {PluginTemplate} from "../../../utils/entities/adminTool/pluginTemplate";
import {EnvProperties} from "../../../utils/properties/env-properties";
import {properties} from 'src/environments/environment';
import {Subscriber} from "rxjs";
import {CustomizationOptions, Layout} from "../../../connect/community/CustomizationOptions";
import {CustomizationService} from "../../../services/customization.service";
export class PluginBaseInfo {
title: string = "Lorem ipsum";
constructor() {
}
compare(oldObject) {
if (!oldObject) {
oldObject = Object.assign(this)
} else {
for (let attrKey of Object.keys(this)) {
if (!oldObject[attrKey] && oldObject[attrKey] != false) {
if (typeof this[attrKey] === "string" || typeof this[attrKey] === "boolean") {
oldObject[attrKey] = this[attrKey];
} else {
oldObject[attrKey] = Object.assign(this[attrKey])
}
}
}
}
return oldObject;
}
}
export class PluginURL {
url: string;
linkText: string;
target: string;
route: boolean;
constructor(url, linkText, target = "_blank", route = false) {
this.url = url;
this.linkText = linkText;
this.target = target;
this.route = route;
}
}
export class PluginInfoCards {
tag?: string;
title: string;
description: string;
urlsArray: PluginURL[];
image?: string;
icon?:string;
show: boolean;
}
@Directive()
export abstract class PluginBaseComponent<T extends PluginBaseInfo> implements OnDestroy {
public properties: EnvProperties = properties;
@Input() plugin: Plugin;
@Input() pluginTemplate: PluginTemplate;
@Input() pluginObject: T;
@Input() previewInAdmin: boolean = false;
subscriptions = [];
customizationOptions: CustomizationOptions;
style:string ='';
fontsDarkMode:boolean = true;
protected layoutService: CustomizationService
constructor( ) {
}
ngOnInit(): void {
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe()
} else if (subscription instanceof Function) {
subscription();
} else if (typeof IntersectionObserver !== 'undefined' && subscription instanceof IntersectionObserver) {
subscription.disconnect();
} else if (typeof ResizeObserver !== 'undefined' && subscription instanceof ResizeObserver) {
subscription.disconnect();
}
});
}
isVisible(field) {
return (this.plugin && this.pluginObject && this.pluginObject[field] == true) /* plugin is on anyway */
|| (!this.plugin && this.pluginTemplate && this.pluginObject && this.pluginObject[field] == true) /* template is on */
}
getLayout(communityId) {
if (this.previewInAdmin) {
let defaultCustomizationOptions = new CustomizationOptions(CustomizationOptions.getIdentity(communityId).mainColor, CustomizationOptions.getIdentity(communityId).secondaryColor);
this.subscriptions.push(this.layoutService.getLayout(this.properties, communityId).subscribe(layout => {
layout = (layout ? layout : new Layout(communityId, defaultCustomizationOptions));
this.customizationOptions = (layout ? CustomizationOptions.checkForObsoleteVersion(layout.layoutOptions, communityId) : Object.assign({}, defaultCustomizationOptions));
this.setStyle()
}, error => {
this.customizationOptions = defaultCustomizationOptions;
this.setStyle();
}));
}
}
setStyle() {
this.style = `background-color: ` + this.customizationOptions.backgrounds.form.color + `;
background-image: ` + (this.customizationOptions.backgrounds.form.imageFile ? (Layout.getUrl(properties.utilsService + '/download/' + this.customizationOptions.backgrounds.form.imageFile)) : 'none') + `;
background-position:` + this.customizationOptions.backgrounds.form.position + `;`
this.fontsDarkMode = this.customizationOptions.backgrounds.form.fontsDarkMode;
}
}

View File

@ -0,0 +1,43 @@
import {Directive, EventEmitter, Input, OnDestroy, Output} from '@angular/core';
import {Plugin} from "../../../utils/entities/adminTool/plugin";
import {PluginTemplate} from "../../../utils/entities/adminTool/pluginTemplate";
import {EnvProperties} from "../../../utils/properties/env-properties";
import {properties} from 'src/environments/environment';
import {PluginBaseComponent, PluginBaseInfo} from "./base-plugin.component";
export class PluginEditEvent {
field:string;
type:"text" | "HTML" | "boolean" | 'parent' |'open-submenu' | 'close-submenu';
value?:any;
constructor(field: string, type: "text" | "HTML" | "boolean" | 'parent' |'open-submenu' | 'close-submenu', value= null) {
this.field = field;
this.type = type;
this.value = value;
}
}
@Directive()
export abstract class PluginBaseFormComponent<T extends PluginBaseInfo> extends PluginBaseComponent<T> implements OnDestroy {
public properties: EnvProperties = properties;
@Input() editMode =false;
@Input() plugin:Plugin;
@Input() pluginTemplate:PluginTemplate;
@Input() editTemplate:boolean = false;
@Input() pluginObject:T;
@Output() valuesChanged:EventEmitter<PluginEditEvent> = new EventEmitter<any>();
subscriptions = [];
pluginEditEvent:PluginEditEvent;
valueChanged($event:PluginEditEvent){
this.pluginObject[$event.field]=$event.value;
this.valuesChanged.emit($event)
}
toggleSubMenu(open:boolean){
this.valuesChanged.emit(new PluginEditEvent(null,open?'open-submenu':'close-submenu'))
}
isVisible(field){
return (this.plugin && this.pluginObject && this.pluginObject[field] == true) /* plugin is on anyway */
|| (!this.plugin && this.pluginTemplate && this.pluginObject && this.pluginObject[field] == true) /* template is on */
}
}

View File

@ -0,0 +1,86 @@
import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core';
import {PluginEditEvent} from "./base-plugin.form.component";
import {AlertModal} from "../../../utils/modal/alert";
import {UntypedFormBuilder, UntypedFormGroup} from "@angular/forms";
@Component({
selector: 'plugin-field-edit',
template: `
<ng-container *ngIf="type=='boolean'">
<mat-slide-toggle [checked]="value" (change)="updateObject($event.checked)"></mat-slide-toggle>
</ng-container>
<ng-container *ngIf="type!='boolean'">
<input *ngIf="type == 'checkbox'" [(ngModel)]="value" [checked]="value" (ngModelChange)="updateObject($event)"
type="checkbox" class="uk-checkbox">
<div *ngIf="type == 'text'" input [value]="value" [placeholder]="placeholder?placeholder:field.toUpperCase()"
type="text" (valueChange)="updateObject($event)" inputClass=" border-bottom "></div>
<div *ngIf="type == 'textarea'" class="uk-grid">
<ng-container *ngIf="switchToHTMLEditor ">
<a class="uk-text-xsmall uk-text-right uk-margin-top uk-width-1-1" (click)="openHTMLEditor()"><span
uk-icon="icon:code; ratio:0.5"></span> open editor</a>
</ng-container>
<div class="uk-width-1-1">
<div input [value]="value" [placeholder]="placeholder?placeholder:field.toUpperCase()" type="textarea"
[rows]="5" (valueChange)="updateObject($event)" inputClass=" uk-padding-remove "
style="min-height: 100px; margin-left:-30px " class="uk-margin-top"></div>
</div>
</div>
</ng-container>
<modal-alert #HTMLEditorModal (alertOutput)="closeHTMLEditor()" [large]="true"
classTitle="uk-background-primary uk-light">
<ckeditor [readonly]="false"
debounce="100"
[formControl]="HTMLForm.get('value')"
[config]="{ extraAllowedContent: '* [uk-*](*) ; span', disallowedContent: 'script; *[on*]',
removeButtons: 'Save,NewPage,DocProps,Preview,Print,' +
'Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,' +
'CreateDiv,Flash,PageBreak,' +
'Subscript,Superscript,Anchor,Smiley,Iframe,Styles,Font,About,Language,JustifyLeft,JustifyRight,JustifyCenter,JustifyBlock,FontSize,TextColor,BGColor',
extraPlugins: 'divarea'}">
</ckeditor>
</modal-alert>
`,
styles: [`
:host >>> textarea.input {
border: solid 1px #3e3e3e3e !important;
}
`]
})
export class PluginFieldEditComponent {
@Input() type;
@Input() value;
@Input() field;
@Input() placeholder;
@Input() switchToHTMLEditor;
@Output() editClicked: EventEmitter<PluginEditEvent> = new EventEmitter<PluginEditEvent>();
@Output() changed: EventEmitter<PluginEditEvent> = new EventEmitter();
htmlEditorView = false;
@ViewChild('HTMLEditorModal') HTMLEditorModal: AlertModal;
HTMLForm: UntypedFormGroup = this._fb.group({
value: this._fb.control("")
});
constructor(private _fb: UntypedFormBuilder) {
}
updateObject(value) {
console.log(value)
this.value = value;
this.changed.emit({field: this.field, value: this.value, type: this.type});
}
openHTMLEditor() {
this.HTMLForm.get('value').setValue(this.value)
this.htmlEditorView = true;
this.HTMLEditorModal.alertTitle = "HTML Editor";
this.HTMLEditorModal.open();
}
closeHTMLEditor() {
this.htmlEditorView = false;
this.updateObject(this.HTMLForm.get('value').value)
}
}

View File

@ -0,0 +1,22 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {PluginFieldEditComponent} from "./plugin-field-edit.component";
import {InputModule} from "../../../sharedComponents/input/input.module";
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
import {CKEditorModule} from "ng2-ckeditor";
import {AlertModalModule} from "../../../utils/modal/alertModal.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, InputModule, MatSlideToggleModule, CKEditorModule, AlertModalModule, FormsModule, ReactiveFormsModule
],
declarations: [PluginFieldEditComponent],
exports: [PluginFieldEditComponent]
})
export class PluginFieldEditModule {
/*constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([])
}*/
}

View File

@ -0,0 +1,164 @@
import {Option} from "../../../sharedComponents/input/input.component";
import {PluginOpenAIREProducts} from "../components/openaireProducts/plugin-openaire-products.component";
import {PluginDiscoverBySubcommunity} from "../components/discover-by-subcommunity/plugin-discover-by-subcommunity.component";
import {PluginBaseInfo, PluginInfoCards, PluginURL} from "./base-plugin.component";
import {PluginGatewayInformation} from "../components/gateway-information/plugin-gateway-information.component";
import {PluginFeaturedDatasets} from "../components/featured-datasets/plugin-featured-datasets.component";
import {PluginSearchDepositLink} from "../components/search-deposit-link/plugin-search-deposit-link.component";
import {PluginOrganizations} from "../components/organizations/plugin-organizations.component";
import {PluginSuggestedRepositories} from "../components/suggested-repositories/plugin-suggested-repositories.component";
import {ParagraphInfo} from "../components/paragraph-info/plugin-graph-info.component";
import {PluginStats} from "../components/stats/plugin-stats.component";
import {PluginCardInfo} from "../components/card-info/plugin-card-info.component";
import {PluginSearchBar} from "../components/search-bar/plugin-search-bar.component";
import {HTMLSection} from "../components/html-section/plugin-html-section.component";
export class PluginUtils{
public attrTypeOptions: Option[] = [
{label:"Text", value:"text"},
{label:"HTML", value:"HTML"},
{label:"Boolean", value:"boolean"},
{label:"URL", value:"URL"},
];
public availablePluginCodesOptions: Option[] = [
{label:"OpenAIRE products", value:"openaire-products"},
{label:"Discover by subcommunity", value:"discover-by-subcommunity"},
{label:"Gateway information", value:"gateway-information"},
{label:"Search/ deposit/ link", value:"search-deposit-link"},
{label:"Learn and Connect", value:"learn-and-connect"},
{label:"How to use", value:"how-to-use"},
{label:"Suggested Repositories", value:"suggested-repositories"},
{label:"Featured Datasets", value:"featured-datasets"},
{label:"Organizations", value:"organizations"},
{label:"Graph info", value:"graph-info"},
{label:"Statistics", value:"stats"},
{label:"Search Bar", value:"search-bar"},
{label:"Card info", value:"card-info"},
{label:"Paragraph info", value:"paragraph-info"},
{label:"HTML section", value:"html-section"},
];
public customOptions: Option[] = [
{label:"Yes", value:"true"},
{label:"no", value:"false"}
];
public availablePluginCodes: string[] = ["openaire-products", "discover-by-subcommunity", "gateway-information", "search-deposit-link", "learn-and-connect", "how-to-use", "suggested-repositories", "featured-datasets", "organizations", "graph-info", "organizations", "stats", "search-bar","card-info", "paragraph-info", "html-section"];
public placementsOptions: Option[] = [
{label:"Right", value:"right"},
{label:"Top", value:"top"},
// {label:"Top Right", value:"top-right"},
// {label:"Center", value:"center"},
{label:"Bottom", value:"bottom"},
{label:"Left", value:"left"},
];
public planOptions: Option[] = [
{value: 'Default', label: 'Default'},
{value: 'Standard', label: 'Standard'},
{value: 'Advanced', label: 'Advanced'},
{value: 'Premium', label: 'Premium'},
{value: 'National', label: 'National'}
];
public static initializeObjectAndCompare(code, oldObject = null){
switch(code) {
case 'openaire-products': {
return (new PluginOpenAIREProducts()).compare(oldObject);
}
case 'discover-by-subcommunity': {
return (new PluginDiscoverBySubcommunity()).compare(oldObject);
}
case 'gateway-information': {
return (new PluginGatewayInformation()).compare(oldObject);
}
case 'search-deposit-link': {
return (new PluginSearchDepositLink()).compare(oldObject);
}
case 'suggested-repositories': {
return (new PluginSuggestedRepositories()).compare(oldObject);
}
case 'featured-datasets': {
return (new PluginFeaturedDatasets()).compare(oldObject);
}
case 'organizations': {
return (new PluginOrganizations()).compare(oldObject);
}
case 'graph-info': {
return (new PluginGraphInfo()).compare(oldObject);
}
case 'paragraph-info': {
return (new ParagraphInfo()).compare(oldObject);
}
case 'html-section': {
return (new HTMLSection()).compare(oldObject);
}
case 'stats': {
return (new PluginStats()).compare(oldObject);
}
case 'learn-and-connect': {
return (new PluginCardInfo()).compare(oldObject);
}
case 'how-to-use': {
return (new PluginCardInfo()).compare(oldObject);
}
case 'card-info': {
return (new PluginCardInfo()).compare(oldObject);
}
case 'search-bar': {
return (new PluginSearchBar()).compare(oldObject);
}
default: {
return (new PluginBaseInfo()).compare(oldObject);
}
}
}
//
public static updateExistingObject(oldObject, object ){
if(!oldObject) {
oldObject = Object.assign(object)
}else{
for (let attrKey of Object.keys(object)) {
if (!oldObject[attrKey] && oldObject[attrKey] != false) {
oldObject[attrKey] = Object.assign(object[attrKey])
}
}
}
return oldObject;
}
}
export class PluginHowToUse extends PluginCardInfo{
title:string ="How to use the gateway?";
cardInfoArray: PluginInfoCards[] = [
{title: "Tutorials", description: "Mini-video tutorials for gateway managers", urlsArray:[ new PluginURL("https://www.youtube.com/playlist?list=PL0c4IRNUxuKcyRUQ_J9BH_EE1amXU6kgp","View all")], show:true},
{title: "Guides", description: "Textual guides on gateway functionalities.", urlsArray:[ new PluginURL("https://www.openaire.eu/research-community-gateway-guide","Guide for the users")/*, new PluginURL("","Guide for the managers")*/], show:true},
{title: "Webinars", description: "Recordings and slides of webinars on different aspects of Open Science.", urlsArray:[ new PluginURL("","View all")], show:true}
];
compare(oldObject){
oldObject = super.compare(oldObject)
for(let card of this.cardInfoArray){
}
return oldObject;
}
}
export class PluginLearnAndConnect extends PluginCardInfo{
title:string ="Learn & Connect with Open Science";
cardInfoArray:PluginInfoCards[] = [
{title: "OS Practices", description: "Open Science best practices for your community, policies and mandates.",
urlsArray:[ new PluginURL("","")], show:true},
{title: "OS Guides for beginners", description: "New to Open Science? Learn the basics!",urlsArray:[ new PluginURL("https://www.openaire.eu/guides","Learn more")], show:true},
{title: "Webinars", description: "Recordings and slides of webinars on different aspects of Open Science.",urlsArray:[ new PluginURL("https://www.openaire.eu/support/webinars","Learn more")], show:true}
];
}
export class PluginGraphInfo extends ParagraphInfo{
title:string ="How? It's about open data and collaboration"
paragraph1:string = `This gateway is built on the OpenAIRE Graph, one of the largest open scholarly record collections worldwide. Conceived as a public and transparent good, populated out of data sources trusted by scientists, the OpenAIRE Graph brings discovery, monitoring, and assessment of science back in the hands of the scientific community.`;
paragraph2:string = "Within a constantly emerging scholarly communication environment, the OpenAIRE Graph is a moving target, continuously integrating new sources, new types of research objects, and embedding impact and usage indicators. We therefore welcome the community to work with us to improve all its aspects: its coverage (geographic and thematic), quality (disambiguation and semantics) and access (APIs).";
url:PluginURL= new PluginURL("https://graph.openaire.eu","Learn more")
image:string = "assets/common-assets/common/graph-nodes.svg"
}

View File

@ -0,0 +1,9 @@
.pluginEditMode{
border:2px solid grey;
padding:10px;
}
:host ::ng-deep .fieldEditMode{
border:1px dashed lightblue;
padding:1px;
margin-bottom: 5px;
}

View File

@ -0,0 +1,73 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {Plugin} from "../../../utils/entities/adminTool/plugin";
import {PluginTemplate} from "../../../utils/entities/adminTool/pluginTemplate";
import {PluginEditEvent} from "../utils/base-plugin.form.component";
import {PluginUtils} from "../utils/pluginUtils";
@Component({
selector: 'plugin-wrapper-form',
template: `
<div class="uk-margin-small-right uk-margin-top" *ngIf="pluginObject">
<ng-container *ngIf="pluginTemplate.code && pluginUtils.availablePluginCodes.indexOf(pluginTemplate.code) != -1; else noplugin">
<ng-container *ngIf="pluginTemplate.code == 'openaire-products'">
<plugin-openaire-products-form [pluginTemplate]="pluginTemplate" [plugin]="plugin" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-openaire-products-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'discover-by-subcommunity'">
<plugin-discover-by-subcommunity-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-discover-by-subcommunity-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'gateway-information'">
<plugin-gateway-information-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-gateway-information-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'search-deposit-link'">
<plugin-search-deposit-link-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate" [editSubmenuOpen]="editSubmenuOpen"></plugin-search-deposit-link-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'suggested-repositories'">
<plugin-suggested-repositories-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-suggested-repositories-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'featured-datasets'">
<plugin-featured-datasets-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-featured-datasets-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'organizations'">
<plugin-organizations-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-organizations-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'graph-info' || pluginTemplate.code == 'paragraph-info'">
<plugin-graph-info-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-graph-info-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'stats'">
<plugin-stats-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-stats-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'search-bar'">
<plugin-search-bar-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-search-bar-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'card-info' || pluginTemplate.code == 'learn-and-connect' || pluginTemplate.code == 'how-to-use'">
<plugin-card-info-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate" [editSubmenuOpen]="editSubmenuOpen"></plugin-card-info-form>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'html-section'">
<plugin-html-section-form [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" (valuesChanged)="changed.emit($event)" [editTemplate]="editTemplate"></plugin-html-section-form>
</ng-container>
</ng-container>
<ng-template #noplugin>
<div class="uk-text-muted uk-text-center">
No plugin available
</div>
</ng-template>
</div>
`,
styleUrls: ["edit-plugin.css"]
})
export class PluginEditWrapperComponent implements OnInit {
@Input() plugin:Plugin;
@Input() pluginTemplate:PluginTemplate;
@Input() editTemplate:boolean;
@Input() pluginObject;
@Output() changed:EventEmitter<PluginEditEvent> = new EventEmitter();
@Input() editSubmenuOpen;
pluginUtils = new PluginUtils();
ngOnInit(): void {
}
}

View File

@ -0,0 +1,35 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {PluginEditWrapperComponent} from "./plugin-edit-wrapper.component";
import {PluginOpenaireProductsFormComponent} from "../components/openaireProducts/plugin-openaire-products.form.component";
import {PluginFieldEditModule} from "../utils/plugin-field-edit.module";
import {PluginDiscoverBySubcommunityFormComponent} from "../components/discover-by-subcommunity/plugin-discover-by-subcommunity.form.component";
import {PluginFeaturedDatasetsFormComponent} from "../components/featured-datasets/plugin-featured-datasets.form.component";
import {PluginGatewayInformationFormComponent} from "../components/gateway-information/plugin-gateway-information.form.component";
import {PluginSearchDepositLinkFormComponent} from "../components/search-deposit-link/plugin-search-deposit-link.form.component";
import {PluginOrganizationsFormComponent} from "../components/organizations/plugin-organizations.form.component";
import {IconsModule} from "../../../utils/icons/icons.module";
import {PluginSuggestedRepositoriesFormComponent} from "../components/suggested-repositories/plugin-suggested-repositories.form.component";
import {PluginGraphInfoFormComponent} from "../components/paragraph-info/plugin-graph-info.form.component";
import {PluginStatsFormComponent} from "../components/stats/plugin-stats.form.component";
import {PluginSearchBarFormComponent} from "../components/search-bar/plugin-search-bar.form.component";
import {PluginCardInfoFormComponent} from "../components/card-info/plugin-card-info-form.component";
import {CKEditorModule} from "ng2-ckeditor";
import {InputModule} from "../../../sharedComponents/input/input.module";
import {PluginHtmlSectionFormComponent} from "../components/html-section/plugin-html-section.form.component";
@NgModule({
imports: [
CommonModule, RouterModule,
ReactiveFormsModule, InputModule,
FormsModule, PluginFieldEditModule, IconsModule, CKEditorModule,
],
declarations: [PluginEditWrapperComponent, PluginOpenaireProductsFormComponent, PluginDiscoverBySubcommunityFormComponent, PluginDiscoverBySubcommunityFormComponent, PluginDiscoverBySubcommunityFormComponent, PluginDiscoverBySubcommunityFormComponent, PluginDiscoverBySubcommunityFormComponent, PluginDiscoverBySubcommunityFormComponent, PluginFeaturedDatasetsFormComponent, PluginGatewayInformationFormComponent, PluginSearchDepositLinkFormComponent, PluginOrganizationsFormComponent, PluginSuggestedRepositoriesFormComponent, PluginGraphInfoFormComponent, PluginStatsFormComponent, PluginSearchBarFormComponent, PluginCardInfoFormComponent, PluginHtmlSectionFormComponent],
exports: [PluginEditWrapperComponent]
})
export class PluginEditWrapperModule {
}

View File

@ -0,0 +1,65 @@
import {Component, Input, OnInit} from '@angular/core';
import {Plugin} from "../../../utils/entities/adminTool/plugin";
import {PluginTemplate} from "../../../utils/entities/adminTool/pluginTemplate";
import {PluginUtils} from "../utils/pluginUtils";
@Component({
selector: 'plugin-wrapper',
template: `
<ng-container *ngIf="pluginTemplate && pluginObject">
<div *ngIf="pluginTemplate.code && pluginUtils.availablePluginCodes.indexOf(pluginTemplate.code) != -1; else noplugin">
<ng-container *ngIf="pluginTemplate.code == 'openaire-products'">
<plugin-openaire-products [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-openaire-products>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'discover-by-subcommunity'">
<plugin-discover-by-subcommunity [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-discover-by-subcommunity>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'gateway-information'">
<plugin-gateway-information [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-gateway-information>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'search-deposit-link'">
<plugin-search-deposit-link [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-search-deposit-link>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'suggested-repositories'">
<plugin-suggested-repositories [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-suggested-repositories>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'featured-datasets'">
<plugin-featured-datasets [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-featured-datasets>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'organizations'">
<plugin-organizations [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-organizations>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'graph-info' || pluginTemplate.code == 'paragraph-info'">
<plugin-graph-info [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-graph-info>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'stats'">
<plugin-stats [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-stats>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'search-bar'">
<plugin-search-bar [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-search-bar>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'card-info' || pluginTemplate.code == 'learn-and-connect' || pluginTemplate.code == 'how-to-use'">
<plugin-card-info [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-card-info>
</ng-container>
<ng-container *ngIf="pluginTemplate.code == 'html-section'">
<plugin-html-section [plugin]="plugin" [pluginTemplate]="pluginTemplate" [pluginObject]="pluginObject" [previewInAdmin]="previewInAdmin" ></plugin-html-section>
</ng-container>
</div>
<ng-template #noplugin>
<div class="uk-text-muted uk-text-center">
No plugin available
</div>
</ng-template>
</ng-container>
`
})
export class PluginWrapperComponent implements OnInit {
@Input() plugin:Plugin;
@Input() pluginObject;
@Input() pluginTemplate:PluginTemplate;
@Input() previewInAdmin:boolean = false;
pluginUtils = new PluginUtils();
ngOnInit(): void {
}
}

View File

@ -0,0 +1,30 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {PluginWrapperComponent} from "./plugin-wrapper.component";
import {PluginOpenaireProductsModule} from "../components/openaireProducts/plugin-openaire-products.module";
import {PluginDiscoverBySubcommunityModule} from '../components/discover-by-subcommunity/plugin-discover-by-subcommunity.module';
import {PluginGatewayInformationModule} from '../components/gateway-information/plugin-gateway-information.module';
import {PluginSearchDepositLinkModule} from '../components/search-deposit-link/plugin-search-deposit-link.module';
import {PluginSuggestedRepositoriesModule} from '../components/suggested-repositories/plugin-suggested-repositories.module';
import {PluginFeaturedDatasetsModule} from '../components/featured-datasets/plugin-featured-datasets.module';
import {PluginOrganizationsModule} from "../components/organizations/plugin-organizations.module";
import {PluginStatsModule} from "../components/stats/plugin-stats.module";
import {PluginSearchBarModule} from "../components/search-bar/plugin-search-bar.module";
import {PluginCardInfoModule} from "../components/card-info/plugin-card-info.module";
import {PluginHtmlSectionModule} from "../components/html-section/plugin-html-section.module";
import {PluginGraphInfoModule} from "../components/paragraph-info/plugin-graph-info.module";
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, PluginOpenaireProductsModule,
PluginDiscoverBySubcommunityModule, PluginSearchDepositLinkModule, PluginSuggestedRepositoriesModule, PluginFeaturedDatasetsModule, PluginGatewayInformationModule, PluginOrganizationsModule, PluginHtmlSectionModule, PluginStatsModule, PluginSearchBarModule, PluginCardInfoModule, PluginGraphInfoModule
],
declarations: [PluginWrapperComponent],
exports: [PluginWrapperComponent]
})
export class PluginWrapperModule {
}

View File

@ -137,7 +137,7 @@ export class PortalsComponent implements OnInit {
this.deletePortalsFromArray(this.selectedPortals); this.deletePortalsFromArray(this.selectedPortals);
NotificationHandler.rise('Portals have been <b>successfully deleted</b>'); NotificationHandler.rise('Portals have been <b>successfully deleted</b>');
this.showLoading = false; this.showLoading = false;
this._clearCacheService.clearCache("Portals deleted"); // this._clearCacheService.clearCache("Portals deleted");
}, },
error => this.handleUpdateError('System error deleting the selected communities', error) error => this.handleUpdateError('System error deleting the selected communities', error)
)); ));
@ -188,7 +188,7 @@ export class PortalsComponent implements OnInit {
portal => { portal => {
this.portalUpdatedSuccessfully(portal); this.portalUpdatedSuccessfully(portal);
NotificationHandler.rise('Portal <b>' + portal.name + '</b> has been <b>successfully updated</b>'); NotificationHandler.rise('Portal <b>' + portal.name + '</b> has been <b>successfully updated</b>');
this._clearCacheService.clearCache("Portal updated"); //this._clearCacheService.clearCache("Portal updated");
}, },
error => this.handleUpdateError('System error updating portal', error) error => this.handleUpdateError('System error updating portal', error)
)); ));
@ -198,7 +198,7 @@ export class PortalsComponent implements OnInit {
portal => { portal => {
this.portalSavedSuccessfully(portal); this.portalSavedSuccessfully(portal);
NotificationHandler.rise('Portal <b>' + portal.name + '</b> has been <b>successfully created</b>'); NotificationHandler.rise('Portal <b>' + portal.name + '</b> has been <b>successfully created</b>');
this._clearCacheService.clearCache("Portal saved"); //this._clearCacheService.clearCache("Portal saved");
}, },
error => this.handleUpdateError('System error creating portal', error) error => this.handleUpdateError('System error creating portal', error)
)); ));

View File

@ -13,6 +13,7 @@ import {ActivatedRoute} from "@angular/router";
<li [class.uk-active]="tab === 'entity'"><a routerLink="../entities">Entities</a></li> <li [class.uk-active]="tab === 'entity'"><a routerLink="../entities">Entities</a></li>
<li *ngIf="portal && type === 'community'" [class.uk-active]="tab === 'menu'"><a routerLink="../menu">Menus</a></li> <li *ngIf="portal && type === 'community'" [class.uk-active]="tab === 'menu'"><a routerLink="../menu">Menus</a></li>
<li *ngIf="isPortalAdmin && !portal" [class.uk-active]="tab === 'class'"><a routerLink="../classes">Classes</a></li> <li *ngIf="isPortalAdmin && !portal" [class.uk-active]="tab === 'class'"><a routerLink="../classes">Classes</a></li>
<li *ngIf="isPortalAdmin && !portal" [class.uk-active]="tab === 'template'"><a routerLink="../templates">Templates</a></li>
<li *ngIf="isPortalAdmin && portal=='connect'" [class.uk-active]="tab === 'customization'"><a routerLink="../customization">Customization</a></li> <li *ngIf="isPortalAdmin && portal=='connect'" [class.uk-active]="tab === 'customization'"><a routerLink="../customization">Customization</a></li>
</ul> </ul>
` `
@ -25,7 +26,7 @@ export class AdminTabsComponent implements OnInit {
@Input() @Input()
public user: User; public user: User;
@Input() @Input()
public tab: "portal" | "page" | "entity" | "menu" | "class" | "customization" = 'page'; public tab: "portal" | "page" | "entity" | "menu" | "class" | "customization" | "template" = 'page';
private subscriptions: any[] = []; private subscriptions: any[] = [];
constructor(private route: ActivatedRoute, private userManagementService: UserManagementService) { constructor(private route: ActivatedRoute, private userManagementService: UserManagementService) {

View File

@ -41,7 +41,7 @@ declare var UIkit;
</div> </div>
</div> </div>
</div> </div>
<div id="page_content_inner" class="uk-container uk-container-large"> <div id="page_content_inner" [class]="fullWidth?'':'uk-container uk-container-large'">
<div [ngClass]="!isMobile?'uk-padding-small uk-padding-remove-vertical':''"> <div [ngClass]="!isMobile?'uk-padding-small uk-padding-remove-vertical':''">
<ng-content select="[inner]"></ng-content> <ng-content select="[inner]"></ng-content>
</div> </div>
@ -61,6 +61,8 @@ export class PageContentComponent implements OnInit, AfterViewInit, OnDestroy {
public headerSticky: boolean = false; public headerSticky: boolean = false;
@Input() @Input()
public border: boolean = true; public border: boolean = true;
@Input()
public fullWidth: boolean = false;
public offset: number; public offset: number;
public shouldSticky: boolean = true; public shouldSticky: boolean = true;
public isMobile: boolean = false; public isMobile: boolean = false;

View File

@ -231,7 +231,8 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
} }
this.filterActiveBySearch(this.filterForm.value.active); this.filterActiveBySearch(this.filterForm.value.active);
this.userManagementService.updateUserInfo(); this.userManagementService.updateUserInfo();
this.clearCacheService.clearCache(this.role + 's of ' + this.id + ' have been updated'); this.clearCacheService.clearCacheInRoute(this.role + 's of ' + this.id + ' have been updated',this.id, "/");
this.clearCacheService.clearCacheInRoute(this.role + 's of ' + this.id + ' have been updated',this.id, "/curators");
NotificationHandler.rise(this.selectedUser + ' <b>is no longer</b> ' + this.role + ' of ' + this.name + ' Dashboard'); NotificationHandler.rise(this.selectedUser + ' <b>is no longer</b> ' + this.role + ' of ' + this.name + ' Dashboard');
this.loadActive = false; this.loadActive = false;
}, error => { }, error => {

Some files were not shown because too many files have changed in this diff Show More