Compare commits

...

79 Commits

Author SHA1 Message Date
Konstantinos Triantafyllou 04a3916389 Merge from develop 2024-05-30 14:50:46 +03:00
Konstantinos Triantafyllou ead1c8f903 Merge remote-tracking branch 'origin/develop' into plugins-functionality 2024-05-30 14:47:11 +03:00
Konstantinos Triantafyllou ea5275da2d Merge branch 'develop' of code-repo.d4science.org:MaDgIK/openaire-library into develop 2024-05-30 13:59:14 +03:00
Konstantinos Triantafyllou 5197f88ade Add slider tabs in indicators multi chart. 2024-05-30 13:59:07 +03:00
Konstantinos Triantafyllou e9eb05de64 [develop]: Remove console log from input component 2024-05-29 19:39:08 +03:00
Konstantinos Triantafyllou 65a60ddad1 [Develop | ADDED]: Add belongsTo configuration for all entities and initialize it in results. 2024-05-29 13:05:04 +03:00
Konstantina Galouni 59fc73bf4d [develop | DONE | FIXED]: In search results, only 1000 relations are fetched and shown - show messages.
1. result-preview.component.html: Added input parameter "resultTitle" to <entity-metadata>.
2. entity-metadata.component.ts: Added @Input() resultTitle: string = null; | When more than 1000 projects or organizations, show +more projects/partners and in modal, show message "Only 1000 Projects/ Partners of {result title} are shown here."
2024-05-28 16:34:16 +03:00
Konstantina Galouni cc6b5aeffe [develop | DONE | CHANGED]: Excluded (filter out) unidentified projects from search.
1. searchProjects.service.ts: Added filter &fq=(projectcode<>"unidentified") in methods "getProjectsforDataProvider()", "advancedSearchProjects()", "getProjectsForOrganizations()", "numOfSearchProjects2()".
2. organization.component.ts: In method call "searchProjectsService.getProjectsForOrganizations()" updated parameter for funder to be in fq instead of keyword query.
3. projects-in-modal.component.ts: In method "updateFilters()", format filterQuery to be in fq instead of keyword query.
4. entitySearch.service.ts: In method "search()", for type "project", added in the query &fq=(projectcode<>"unidentified").
2024-05-28 15:27:33 +03:00
Konstantinos Triantafyllou 1ac4365e05 [develop | DONE]: Add Role Utils with naming variables for roles 2024-05-28 12:21:37 +03:00
argirok 5af682b1b6 [develop | DONE | CHANGED ] Claim funding: allow search for projects with no funder selected, exclde unidentified, give more space to form 2024-05-28 12:09:21 +03:00
Konstantina Galouni 9722024643 [develop | DONE | FIXED]: relatedDatasourcesTab.component.ts: Show "top 100" message only if results are more than 90 & [BUG FIX] Use "collectedFromName" input and not a predefined static data source name. 2024-05-27 11:20:24 +03:00
argirok 9fb155d95f [develop | DONE | FIXED ] Claims: remove unused import 2024-05-24 10:08:57 +03:00
argirok ec980e1b87 [plugins-functionality | DONE | FIXED ] plugins minor fixes 2024-05-23 12:55:45 +03:00
argirok 8ee93a7239 [plugins-functionality | DONE | CHANGED ] full width option 2024-05-23 12:53:53 +03:00
argirok e7bbe7a359 [plugins-functionality | DONE | ADDED ] add and delete custom plugins, edit plugin in distinct route, add prompt to go back to plugins list 2024-05-22 11:09:18 +03:00
argirok 7decc58f61 [pluginsFunctionality | DONE | CHANGED] Deposit: add Suggested repos link 2024-05-17 10:04:33 +03:00
argirok e831cb03dc [pluginsFunctionality | DONE | CHANGED] plugin suggested repositories - use HTML for repo message 2024-05-17 10:03:52 +03:00
argirok 62f16a6e57 [plugins-functionality | DONE | ADDED ] add filter for active plugins 2024-05-16 15:15:00 +03:00
argirok e5a98845a7 [plugins-functionality | DONE | ADDED ] HTML editor switch 2024-05-16 15:12:54 +03:00
argirok 9c370fd53b [plugins-functionality | DONE | ADDED ] add optional link in stats plugin 2024-05-16 15:03:07 +03:00
argirok 1b99c3b405 [plugins-functionality | DONE | ADDED ] add display title and shortitle and use them instead of title/ short title 2024-05-14 14:49:59 +03:00
argirok 2bfd744ab8 [plugins-functionality | DONE | CHANGED ] update plan values 2024-05-09 10:23:42 +03:00
argirok b0df5c0f31 [plugins-functionality | DONE | FIX ] minor fixes in plugins 2024-05-09 10:22:19 +03:00
argirok 327fe64293 Merge remote-tracking branch 'origin/plugins-functionality' into plugins-functionality 2024-05-09 10:19:42 +03:00
argirok 01554f58f5 [pluginsFunctionality | DONE | CHANGED] remove cache from plugins, configuration and helper services 2024-05-09 10:18:20 +03:00
argirok 6c1c3ef2b2 [pluginsFunctionality | DONE | CHANGED] sdg page: add helptexts if input available 2024-05-09 10:17:33 +03:00
argirok 1abd7c111f [pluginsFunctionality | DONE | CHANGED] plugin-gateway-information.component.html make result numbers look like a link 2024-05-09 10:16:49 +03:00
argirok 6560bd0cd9 [plugins-functionality | DONE | FIX ] zenodo communities use alias instead of internal zenodo id 2024-05-08 12:15:06 +03:00
argirok 13ab093d79 [plugins-functionality | DONE | FIX ] update monitor component 2024-04-25 15:27:19 +03:00
argirok 005f636446 [plugins-functionality | DONE | ADDED ] add generic plugin card info, add search bar plugin, remove separate learn and connect 2024-04-25 15:26:36 +03:00
argirok 678908df5f Merge remote-tracking branch 'origin/develop' into plugins-functionality 2024-04-19 12:41:05 +03:00
argirok 1882ea10fa updates after merge 2024-04-10 13:20:55 +03:00
argirok f5414efaac Merge remote-tracking branch 'origin/develop' into plugins-functionality
# Conflicts:
#	role-verification/role-verification.component.ts
2024-04-10 13:11:37 +03:00
argirok f5850aa781 [pluginsFunctionality | DONE | FIXED] Plugin Openaire services: fix no services appear 2024-04-09 10:48:23 +03:00
argirok d2cc0b0f33 [plugins-functionality | DONE | CHANGED ] Search-link deposit: fixes for slider 2024-04-08 11:49:14 +03:00
argirok 3650b11215 [plugins-functionality | DONE | CHANGED ] Stats: use stats profiles based on community PID, update prod profile 2024-04-08 11:48:38 +03:00
argirok cd186590b7 [plugins-functionality | WIP ] clean up plugin utils 2024-04-03 10:27:28 +03:00
argirok fde8e05922 [plugins-functionality | WIP ] Plugins change background when preview in admin 2024-04-03 10:26:41 +03:00
argirok 9044ed174f [plugins-functionality | DONE | CHANGED ] Change the way the cache is cleared 2024-04-03 10:26:29 +03:00
argirok 750b279ed3 [plugins-functionality | WIP ] Plugins change background when preview in admin 2024-04-01 13:15:52 +03:00
argirok 50051f2de8 Merge remote-tracking branch 'origin/develop' into plugins-functionality 2024-03-28 13:49:59 +02:00
argirok a1b49630db [plugins-functionality | WIP ] updates and fixes after initial beta release 2024-03-28 12:37:00 +02:00
argirok 25051df626 [plugins-functionality | DONE | CHANGED] update plugin service methods signatures to contain pid, to be able to apply authorization 2024-03-27 13:08:52 +02:00
argirok 8eba807906 [pluginsFunctionality | DONE | CHANGED] add property forceCacheReload, for requests that pass from cache (useLongCache=true) check and pass forceReload parameter, get from cache plugin requests 2024-03-27 09:29:07 +02:00
argirok 7d5b82e0dc [plugins-functionality | WIP] 2024-03-15 20:19:31 +02:00
argirok e781dc8a51 [plugins-functionality | DONE | CHANGED] give option to for content, deposit or both, use a common form to edit the options + the criteria 2024-03-15 15:58:15 +02:00
argirok b91822db64 [plugins-functionality | WIP] more updates and fixes 2024-03-15 15:56:54 +02:00
argirok 0aa2ec20e6 Merge remote-tracking branch 'origin/develop' into plugins-functionality 2024-03-14 09:29:51 +02:00
argirok a50d5dc509 Merge remote-tracking branch 'origin/develop' into plugins-functionality 2024-03-13 13:19:38 +02:00
argirok 838a3ef218 [plugins-functionality | WIP] 2024-03-13 10:33:02 +02:00
argirok aaee50875d [plugins-functionality | WIP] add stats plugin 2024-03-13 09:03:58 +02:00
argirok cdde6d8587 [plugins-functionality | DONE | FIX] initialize properly view for master zenodo community 2024-03-11 14:08:51 +02:00
argirok e2b34b13ee [plugins-functionality | WIP] add graph info 2024-03-11 13:29:29 +02:00
argirok e177918b5d [plugins-functionality | WIP] 2024-03-11 13:27:26 +02:00
argirok 2bb981c489 Merge branch 'develop' into plugins-functionality 2024-03-07 11:22:30 +02:00
argirok f5ec98eb88 [plugins-functionality | WIP] affiliations update the way to get community id, updates on plugins 2024-03-06 15:26:14 +02:00
argirok 17e3cda685 [plugins-functionality | WIP] add sliders, update gateway info with search bar, sdgs, fos, community title & description, update suggested repositories and forms 2024-03-01 10:32:38 +02:00
argirok 9ad2da0fd3 [plugins-functionality | WIP] content providers: update methods, add options to select for deposit and add deposition message 2024-02-28 14:46:29 +02:00
argirok c011c9b38c [plugins-functionality | WIP] updates on plugins 2024-02-28 13:07:31 +02:00
argirok d6dc2b040d [plugins-functionality | WIP] move affiliations component to be used in library - plugins 2024-02-22 12:57:52 +02:00
argirok aa0da38de9 [plugins-functionality | WIP] checks in gateway info plugins, form and layout for search-deposit-link 2024-02-22 12:15:21 +02:00
argirok f92c4cbf52 [plugins-functionality | WIP] add more plugins, update forms... 2024-02-22 11:09:20 +02:00
Alex Martzios 552edbd0e2 [plugins-functionality | WIP] move curators component in openaireLibrary 2024-02-05 09:42:12 +02:00
Alex Martzios 34ef34fc00 [plugins-functionality | WIP] add zenodo service as provider in plugin-gateway-information 2024-02-02 13:13:09 +02:00
Alex Martzios 2b91fe2b95 [plugins-functionality | WIP] add search services as providers in plugin-gateway-information 2024-02-02 12:29:49 +02:00
argirok a260ed17bd [plugin-functionalities | WIP] : update plugin forms, add reording, filtering by position, create multiple templates per position, etc 2024-02-02 09:33:01 +02:00
Alex Martzios 3ec805c51c [plugins-functionality | WIP] create plugins on separate folders/components 2024-01-31 11:05:46 +02:00
argirok a373357ccf [plugin-functionalities | WIP] : improvements in template forms (options for plugin code, filter pages based on portaltype, prefill plan option, initialize properly object 2024-01-22 12:37:48 +02:00
argirok d0b4fa7750 [plugins-functionality | WIP] : add component preview when managing plugins, add edit inside plugin preview, add plugin wrapper 2024-01-19 10:53:17 +02:00
argirok 71df792e49 Merge branch 'develop' into plugins-functionality 2023-11-10 13:07:42 +02:00
argirok 06aacd86c4 Merge branch 'angular-16' into plugins-functionality 2023-10-27 11:50:08 +03:00
argirok 4751f64216 Merge branch 'angular-16' into plugins-functionality 2023-10-18 15:30:42 +03:00
argirok ea116a2b10 manage plugins of a template 2023-10-17 09:20:16 +03:00
argirok 8b9c8ec665 Merge remote-tracking branch 'origin/angular-16' into plugins-functionality 2023-10-09 13:53:35 +03:00
argirok 225a9a113f Merge branch 'develop' into plugins-functionality 2023-10-06 21:09:10 +03:00
argirok 2cb0473303 manage plugins button 2023-10-02 12:31:53 +03:00
argirok d80db44df1 improvements in manage Plugins 2023-10-02 10:20:36 +03:00
argirok 4dcb757c1b improvements in manage Plugin Templates
add manage plugins per page + create plugin based on a template
2023-09-26 17:32:27 +03:00
argirok f19d9b3d87 Initial commit for plugins functionality:
Manage Plugin Templates
2023-09-25 11:36:05 +03:00
148 changed files with 6646 additions and 396 deletions

View File

@ -1,11 +1,11 @@
<div class="uk-width-xlarge@l uk-width-large" [ngClass]="centerAlign ? 'uk-align-center':''">
<div class="uk-width-expand" [ngClass]="centerAlign ? 'uk-align-center':''">
<advanced-search-input (searchEmitter)="search(page,size)">
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
[options]="showOptions.selectOptions" class="uk-width-auto "></div>
[options]="showOptions.selectOptions" class="uk-width-medium@xl uk-width-auto"></div>
<div *ngIf="funderOptions && funderOptions.length > 0" input type="select" [(value)]="selectedFunder" placeholder="Funder" hint="Select Funder..."
[options]="funderOptions" class="uk-width-expand" (valueChange)="funderChanged($event)"></div>
<div *ngIf="selectedFunder && selectedFunder.number > 1" class="uk-width-expand" input type="text" [(value)]="keyword" [searchable]="true" placeholder="Projects to link"
[hint]="'Search for ' + openaireEntities.PROJECTS + '...'" tooltip="true" [disabled]="!selectedFunder"></div>
<div class="uk-width-expand" input type="text" [(value)]="keyword" [searchable]="true" placeholder="Projects to link"
[hint]="'Search for ' + openaireEntities.PROJECTS + '...'" tooltip="true" [disabled]="isNoProjectFunder"></div>
</advanced-search-input>
</div>
<div *ngIf=" openaireResultsStatus != errorCodes.LOADING && !isNoProjectFunder && this.selectedFunder && openaireResults.length == 0">
@ -14,7 +14,7 @@
</div>
</div>
<div *ngIf=" openaireResultsStatus != errorCodes.LOADING && this.funderOptions.length > 1 && !this.selectedFunder">
<div class="uk-text-center uk-text-large uk-text-meta uk-margin-large-top">Select funder to proceed
<div class="uk-text-center uk-text-large uk-text-meta uk-margin-large-top">Select funder or search for projects to proceed
</div>
</div>
<div class="uk-margin-top">
@ -65,7 +65,7 @@
</div>
<claim-results [localStoragePrefix]="localStoragePrefix" [results]=openaireResults
[selectedResults]=selectedProjects [basketLimit]="basketLimit"></claim-results>
<div *ngIf="isNoProjectFunder && openaireResultsStatus != errorCodes.LOADING " class="uk-alert uk-alert-default"><span class=" uk-text-bold">{{selectedFunder.name}}</span> has no projects. Proceed to next step. </div>
<div *ngIf="isNoProjectFunder && openaireResultsStatus != errorCodes.LOADING " class="uk-alert uk-alert-default">No projects for funder <span class=" uk-text-bold">{{selectedFunder.name}}</span>. </div>
<div *ngIf="openaireResultsNum != null && openaireResultsNum > 0 && openaireResultsStatus != errorCodes.LOADING " class="uk-flex uk-flex-center ">
<paging-no-load [currentPage]="openaireResultsPage"
[totalResults]="openaireResultsNum" [term]="keyword"

View File

@ -11,7 +11,6 @@ import {OpenaireEntities, SearchFields} from "../../utils/properties/searchField
import {NewSearchPageComponent} from "../../searchPages/searchUtils/newSearchPage.component";
import {Subscriber} from "rxjs";
import { properties } from 'src/environments/environment';
import {error} from "protractor";
declare var UIkit:any;
@ -75,6 +74,8 @@ export class ClaimProjectsSearchFormComponent {
this.sub = this._projectService.advancedSearchProjects("", 1, 0, this.properties,
this.refineFieldsQuery, this.refineFields, "&type=projects&sf=funder").subscribe(
data => {
let option = {value : null, label: "No funder selected"};
this.funderOptions.push(option);
for(let v of data[2][0].values){
let option = {value : v, label: v.name};
this.funderOptions.push(option);
@ -108,7 +109,7 @@ export class ClaimProjectsSearchFormComponent {
this.prevFilters = this.filters;
//searchProjects (params: string, refineParams:string, page: number, size: number, refineFields:string[] , properties:EnvProperties ):any {
this.sub = this._projectService.advancedSearchProjects(this.createOpenaireQueryParams(), page, size, this.properties, null, [], this.createOpenaireRefineQuery()).subscribe(
this.sub = this._projectService.advancedSearchProjects(this.createOpenaireQueryParams(), page, size, this.properties, this.createOpenaireRefineQuery(), [], null).subscribe(
// this.sub = this._projectService.searchProjects(this.createOpenaireQueryParams(),(page==1)? this.refineFieldsQuery:null, page, size, (page==1)?this.refineFields:[], this.properties).subscribe(
data => {
if (data != null) {
@ -151,7 +152,7 @@ export class ClaimProjectsSearchFormComponent {
const entity: ClaimEntity = new ClaimEntity();
entity.project = new ClaimProject();
entity.project.funderId = item.funderId;
entity.project.funderShortname = item.funderShortname?item.funderShortname:(entity.project.funderId.split("::")[1]);
entity.project.funderShortname = item.funderShortname?item.funderShortname:(entity.project.funderId?entity.project.funderId.split("::")[1]:"");
entity.project.funderName = item.funderName;
entity.id = item.id;
entity.project.url = (item.code !="unidentified") ? properties.searchLinkToProject + entity.id : null;
@ -187,12 +188,6 @@ export class ClaimProjectsSearchFormComponent {
}
createOpenaireRefineQuery(): string {
/*if(this.startYear.length > 0 ){
query+='&fq=projectstartyear exact \"'+this.startYear+'\"'
}
if(this.endYear.length > 0 ){
query+='&fq=projectendyear exact \"'+this.endYear+'\"'
}*/
let allFqs = "";
for (let filter of this.filters) {
if (filter.countSelectedValues > 0) {
@ -210,8 +205,11 @@ export class ClaimProjectsSearchFormComponent {
}
}
}
if(this.isNoProjectFunder){
allFqs += "&fq=" + StringUtils.URIEncode( "funder exact " + (StringUtils.quote(this.selectedFunder.id))); ;
if(this.selectedFunder){
allFqs += "&fq=" + StringUtils.URIEncode( "funder exact " + (StringUtils.quote(this.selectedFunder.id)));
}
if(!this.isNoProjectFunder || !this.selectedFunder){
allFqs += '&fq=(projectcode<>"unidentified")'
}
for (let i = 0; i < this.rangeFilters.length; i++) {
let filter = this.rangeFilters[i];

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();
community.title = resData.name;
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.queryId = resData.queryId;
community.logoUrl = resData.logoUrl;
@ -102,6 +104,7 @@ export class CommunityService {
community.claim = resData.claim;
community.membership = resData.membership;
community.type = resData.type;
community.plan = resData.plan?resData.plan:"Default";
community.otherZenodoCommunities = resData.otherZenodoCommunities;
if (resData.hasOwnProperty('status')) {
community.status = resData.status;

View File

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

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

@ -12,7 +12,7 @@ export class ConnectHelper {
if(properties.environment == "development" &&
(properties.adminToolsPortalType == "connect" || properties.adminToolsPortalType == "community"
|| properties.adminToolsPortalType == "aggregator" || properties.adminToolsPortalType == "eosc")) {
domain = "covid-19.openaire.eu"; //for testing
domain = "enermaps.openaire.eu"; //for testing
}
domain = domain.indexOf("//") != -1? domain.split("//")[1]:domain; //remove https:// prefix
if (domain.indexOf('eosc-portal.eu') != -1) {

View File

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

View File

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

View File

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

View File

@ -143,7 +143,7 @@ export class DivIdsComponent implements OnInit {
this.deleteDivIdsFromArray(this.selectedDivIds);
NotificationHandler.rise('Classes have been <b>successfully deleted</b>');
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)
));
@ -195,7 +195,7 @@ export class DivIdsComponent implements OnInit {
divId => {
this.divIdSavedSuccessfully(divId);
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)
));
@ -204,7 +204,7 @@ export class DivIdsComponent implements OnInit {
divId => {
this.divIdUpdatedSuccessfully(divId);
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)
));

View File

@ -166,7 +166,7 @@ export class ClassContentFormComponent implements OnInit {
this._router.navigate(['../'], {queryParams: {"pageId": this.pageId}, relativeTo: this.route});
NotificationHandler.rise('Page content has been <b>successfully updated</b>');
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)
));

View File

@ -155,7 +155,7 @@ export class ClassHelpContentsComponent implements OnInit {
this.deletePageHelpContentsFromArray(this.selectedPageContents);
NotificationHandler.rise('Page content(s) has been <b>successfully deleted</b>');
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)
));
@ -198,7 +198,7 @@ export class ClassHelpContentsComponent implements OnInit {
this.countClassHelpContents();
this.applyCheck(false);
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)
));

View File

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

View File

@ -199,7 +199,7 @@ export class PageContentFormComponent implements OnInit {
NotificationHandler.rise('Page content has been <b>successfully ' + (this.pageContentId ? 'updated' : 'created') + '</b>');
this._router.navigate(['../'], {queryParams: {"pageId": this.pageId}, relativeTo: this.route});
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)
));

View File

@ -165,7 +165,7 @@ export class PageHelpContentsComponent implements OnInit {
this.deletePageHelpContentsFromArray(this.selectedPageContents);
NotificationHandler.rise('Page content(s) has been <b>successfully deleted</b>');
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)
));
@ -210,7 +210,7 @@ export class PageHelpContentsComponent implements OnInit {
NotificationHandler.rise('Page content(s) has been <b>successfully updated</b>');
this.countPageHelpContents();
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)
));

View File

@ -271,8 +271,8 @@ export class MenuComponent implements OnInit {
this.deleteMenuItemFromArray(this.selectedMenuItem, this.isChild);
NotificationHandler.rise("Menu item have been <b>successfully deleted</b>");
this.showLoading = false;
this._clearCacheService.clearCache("Menu item deleted");
this._clearCacheService.purgeBrowserCache("Menu item deleted", this.portal);
this._clearCacheService.clearCacheInRoute("Menu item deleted",this.portal, "/");
},
error => this.handleError("Server error deleting menu item", error)
)
@ -313,8 +313,7 @@ export class MenuComponent implements OnInit {
menuItem => {
this.menuItemSavedSuccessfully(menuItem, true);
NotificationHandler.rise('Menu item <b>' + menuItem.title + '</b> has been <b>successfully created</b>');
this._clearCacheService.clearCache("Menu item saved");
this._clearCacheService.purgeBrowserCache("Menu item saved", this.portal);
this._clearCacheService.clearCacheInRoute("Menu item saved",this.portal, "/");
},
error => this.handleError("System error creating menu item", error)
)
@ -325,8 +324,7 @@ export class MenuComponent implements OnInit {
menuItem => {
this.menuItemSavedSuccessfully(menuItem, false);
NotificationHandler.rise('Menu item <b>' + menuItem.title + '</b> has been <b>successfully updated</b>');
this._clearCacheService.clearCache("Menu item updated");
this._clearCacheService.purgeBrowserCache("Menu item updated", this.portal);
this._clearCacheService.clearCacheInRoute("Menu item updated",this.portal, "/");
},
error => this.handleError("System error updating menu item", error)
)
@ -392,8 +390,7 @@ export class MenuComponent implements OnInit {
HelperFunctions.swap(temp, index, newIndex);
this._helpContentService.reorderMenuItems(temp, this.portal).subscribe(() => {
HelperFunctions.swap(this.featuredMenuItems, index, newIndex);
this._clearCacheService.clearCache("Menu items reordered");
this._clearCacheService.purgeBrowserCache("Menu items reordered", this.portal);
this._clearCacheService.clearCacheInRoute("Menu items reordered",this.portal, "/");
}, error => {
this.handleError("System error reordering menu items", error);
});
@ -405,8 +402,7 @@ export class MenuComponent implements OnInit {
HelperFunctions.swap(temp, index, newIndex);
this._helpContentService.reorderMenuItems(temp, this.portal).subscribe(() => {
HelperFunctions.swap(children && children.length ? children : this.normalMenuItems, index, newIndex);
this._clearCacheService.clearCache("Menu items reordered");
this._clearCacheService.purgeBrowserCache("Menu items reordered", this.portal);
this._clearCacheService.clearCacheInRoute("Menu items reordered",this.portal, "/");
}, error => {
this.handleError("System error reordering menu items", error);
});
@ -421,8 +417,7 @@ export class MenuComponent implements OnInit {
} else {
this.showNormalMenu = status;
}
this._clearCacheService.clearCache("Menu toggled");
this._clearCacheService.purgeBrowserCache("Menu toggled", this.portal);
this._clearCacheService.clearCacheInRoute("Menu toggled",this.portal, "/");
NotificationHandler.rise("Menu has been <b>successfully toggled to be "+(status?"visible":"hidden")+"</b>");
}, error => {
this.handleError("System error toggling menu", error);
@ -434,8 +429,7 @@ export class MenuComponent implements OnInit {
this.subscriptions.push(
this._helpContentService.alignMenu(MenuAlignment[alignment], this.portal).subscribe(() => {
this.featuredAlignment = alignment;
this._clearCacheService.clearCache("Menu aligned");
this._clearCacheService.purgeBrowserCache("Menu aligned", this.portal);
this._clearCacheService.clearCacheInRoute("Menu aligned",this.portal, "/");
NotificationHandler.rise("Menu has been <b>successfully "+alignment.toLowerCase()+" aligned</b>");
}, 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-grid uk-grid-small uk-flex-nowrap uk-grid-divider uk-flex-right" uk-grid>
<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 class="uk-padding-small uk-padding-remove-horizontal">
<a class="uk-button uk-button-link uk-text-truncate"
[queryParams]="{pageId: check.page._id}"
routerLink="../helptexts">
Manage page help texts
<span *ngIf="pageHelpContentsCount[check.page._id]">({{pageHelpContentsCount[check.page._id]}}
)</span>
<span *ngIf="pageHelpContentsCount[check.page._id]">({{pageHelpContentsCount[check.page._id]}})</span>
</a>
</div>
</div>
@ -105,8 +114,7 @@
[queryParams]="{ pageId: check.page._id}"
routerLink="../classContents">Manage class help texts
<span
*ngIf="pageClassContentsCount[check.page._id]">({{pageClassContentsCount[check.page._id]}}
)</span>
*ngIf="pageClassContentsCount[check.page._id]">({{pageClassContentsCount[check.page._id]}})</span>
</a>
</div>
</div>
@ -122,6 +130,16 @@
</ng-container>
<ng-container
*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 class="uk-padding-small uk-padding-remove-horizontal">
<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 {ClearCacheService} from "../../services/clear-cache.service";
import {NotificationHandler} from "../../utils/notification-handler";
import {PluginsService} from "../../services/plugins.service";
@Component({
selector: 'pages',
@ -68,10 +69,11 @@ export class PagesComponent implements OnInit {
private index: number;
pageHelpContentsCount = {};
pageClassContentsCount = {};
pagePluginTemplatesCount = {};
constructor(private element: ElementRef, private route: ActivatedRoute,
private title: Title,
private _router: Router, private _helpContentService: HelpContentService,
private _pluginsService: PluginsService,
private userManagementService: UserManagementService, private _fb: UntypedFormBuilder,
private communityService: CommunityService,
private stakeholderService: StakeholderService,
@ -141,8 +143,9 @@ export class PagesComponent implements OnInit {
},
error => this.handleError('System error retrieving pages', error)));
if (this.portal) {
this.getPageHelpContentsCounts(this.portal);
this.getCountsPerPID(this.portal);
}
this.getPluginTemplatesContentsCounts()
}
ngOnDestroy(): void {
@ -249,8 +252,8 @@ export class PagesComponent implements OnInit {
this.deletePagesFromArray(this.selectedPages);
NotificationHandler.rise('Pages have been <b>successfully deleted</b>');
this.showLoading = false;
this._clearCacheService.clearCache("Pages deleted");
this._clearCacheService.purgeBrowserCache("Pages deleted", this.portal);
// this._clearCacheService.clearCache("Pages deleted");
// this._clearCacheService.purgeBrowserCache("Pages deleted", this.portal);
},
error => this.handleUpdateError('System error deleting the selected pages', error)
));
@ -317,8 +320,8 @@ export class PagesComponent implements OnInit {
page => {
this.pageSavedSuccessfully(page, true);
NotificationHandler.rise('Page <b>' + page.name + '</b> has been <b>successfully created</b>');
this._clearCacheService.clearCache("Page saved");
this._clearCacheService.purgeBrowserCache("Page saved", this.portal);
// this._clearCacheService.clearCache("Page saved");
// this._clearCacheService.purgeBrowserCache("Page saved", this.portal);
},
error => this.handleUpdateError('System error creating page', error)
));
@ -327,8 +330,8 @@ export class PagesComponent implements OnInit {
page => {
this.pageSavedSuccessfully(page, false);
NotificationHandler.rise('Page <b>' + page.name + '</b> has been <b>successfully updated</b>');
this._clearCacheService.clearCache("Page updated");
this._clearCacheService.purgeBrowserCache("Page updated", this.portal);
// this._clearCacheService.clearCache("Page updated");
// this._clearCacheService.purgeBrowserCache("Page updated", this.portal);
},
error => this.handleUpdateError('System error updating page', error)
));
@ -412,7 +415,7 @@ export class PagesComponent implements OnInit {
this.checkboxes[i].page.isEnabled = status;
}
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);
},
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(
pageHelpContentsCount => {
this.pageHelpContentsCount = pageHelpContentsCount;
@ -437,5 +440,19 @@ export class PagesComponent implements OnInit {
this.pageClassContentsCount = pageClassContentsCount;
},
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,236 @@
<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 *ngIf="selectedEntity === 'result' && input.focused"
(click)="$event.stopPropagation();advanced.focusNext(input, $event)"
class="uk-dropdown uk-display-block uk-margin-small-top uk-width-auto" uk-dropdown="mode: hover">
<div class="uk-padding-small">
<quick-selections [resultTypes]="resultTypes" [quickFilter]="resultsQuickFilter"></quick-selections>
</div>
</div>
</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">
Content Providers
<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,280 @@
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'>Content Providers</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.selectedEntity == "result" && this.resultsQuickFilter && this.resultsQuickFilter.selected) {
parameterNames.push(this.resultsQuickFilter.filterId);
parameterValues.push('"'+ encodeURIComponent(this.resultsQuickFilter.value)+'"');
}
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,142 @@
import {ChangeDetectorRef, 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";
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 *ngIf="selectedEntity === 'result' && input.focused" (click)="$event.stopPropagation();advanced.focusNext(input, $event)" class="uk-dropdown uk-display-block uk-margin-small-top uk-width-auto" uk-dropdown="mode: click">
<div class="uk-padding-small">
<quick-selections [resultTypes]="resultTypes"></quick-selections>
</div>
</div>
</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,45 @@
<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 *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";
compare(oldObject): any {
console.log()
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,25 @@
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>
<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" >
<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._router.navigate(["../"], {queryParams: {pageId:this.selectedPageId}, relativeTo: this.route} )
this.selectedTemplate = null;
this.selectedPlugin = null;
},
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,201 @@
<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>{{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">
<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,517 @@
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(_ => {
console.log("pl template", _.code, _.custom)
let plugin: Plugin = null;
for (let pl of plugins) {
if (pl.templateId == _._id) {
plugin = pl;
}
}
if (!plugin && !_.custom) {
plugin = new Plugin(this.selectedPageId, this.selectedCommunityPid, _);
this.plugins.push(plugin);
}
if (plugin) {
console.log("plugin found", plugin.custom)
if (plugin.custom) {
console.log(plugin, _)
}
plugin.object = PluginUtils.initializeObjectAndCompare(_.code, plugin.object)
this.pluginsByPlacement.get(plugin.placement).push({plugin: plugin, template: _, openPreview: false});
}
});
/* console.log("________", )
//add custom plugins in the list
this.plugins.forEach(_ => {
if(_.custom){
console.log("custom plugin", _.templateCode)
let customTemplate = null;
this.pluginTemplates.forEach(template => {
if (_.templateId == template._id) {
customTemplate = template;
}
});
if(customTemplate){
console.log("template found!")
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;
})
}
console.log(availablePlacements)
if (availablePlacements.length == 1) {
this.selectedPlacementView = availablePlacements[0];
this.sinlgePlacementAvailable = true
}
console.log(availablePlacements)
this.showLoading = false;
},
error => this.handleError('System error retrieving plugins', error)));
},
error => this.handleError('System error retrieving templates', error)));
}
/*
public edit(plugin:Plugin, template:PluginTemplate, placement, index) {
this.editView = true;
this.selectedPlugin = JSON.parse(JSON.stringify(plugin)); // deep copy object with nested objects
this.selectedTemplate = template;
this.index = index;
this.pagesCtrl = this._fb.array([], Validators.required);
this.templateForm = this._fb.group({
_id: this._fb.control(plugin._id),
pid: this._fb.control(this.selectedCommunityPid),
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)
}
));
}
}
}
*/
/*
public newPluginSelectTemplate() {
this.selectedPlugin = null;
this.editView = true;
if(!this.templateView) {
this.selectedTemplate = null;
this.selectTemplateView = true;
}else{
this.newPlugin( Object.assign({}, this.template));
}
}*/
/*
public newPlugin(template) {
this.selectedTemplate = template;
this.templateForm = this._fb.group({
_id: this._fb.control(null),
pid: this._fb.control(this.selectedCommunityPid),
page: this._fb.control(this.selectedPageId),
code: this._fb.control(this.selectedTemplate.code, Validators.required),
placement: this._fb.control(this.selectedTemplate.placement),
order: this._fb.control(""),
active: this._fb.control(false),
isPriorTo: this._fb.control(false),
values: this._fb.array([]),
object: this._fb.control({})
});
for (let attrKey of Object.keys(this.selectedTemplate.settings)) {
(this.templateForm.get("values") as FormArray).push(this._fb.group({
key: this._fb.control(attrKey),
value: this._fb.control(this.selectedTemplate.settings[attrKey].value ? this.selectedTemplate.settings[attrKey].value : ""),
}));
}
this.selectTemplateView = false;
}
*/
/*public saveConfirmed(index) {
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, this.index)
}*/
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.editView = false;
// this.selectTemplateView = false;
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)
));
}
/* 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);
}
}
public getPagesAsString(pageIds): string {
let pages = [];
for (let id of pageIds) {
pages.push(this.allPages.filter(option => option.value._id == id).map((option => option.value.name)));
}
return pages.join(", ");
}
public getPageById(pageId) {
for (let option of this.allPages) {
if (option.value._id == pageId) {
return option.value;
}
}
return pageId;
}
getKeys(obj) {
return obj ? Object.keys(obj) : [];
}
/*
reset() {
if (this.selectedPlugin) {
this.edit(this.pluginsByPlacement.get(this.selectedTemplate.placement)[this.index].plugin, this.selectedTemplate, this.selectedTemplate.placement, this.index)
} else {
this.newPlugin(this.selectedTemplate)
}
}
*/
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);
}
}
/*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();
}
*/
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);
NotificationHandler.rise('Portals have been <b>successfully deleted</b>');
this.showLoading = false;
this._clearCacheService.clearCache("Portals deleted");
// this._clearCacheService.clearCache("Portals deleted");
},
error => this.handleUpdateError('System error deleting the selected communities', error)
));
@ -188,7 +188,7 @@ export class PortalsComponent implements OnInit {
portal => {
this.portalUpdatedSuccessfully(portal);
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)
));
@ -198,7 +198,7 @@ export class PortalsComponent implements OnInit {
portal => {
this.portalSavedSuccessfully(portal);
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)
));

View File

@ -13,6 +13,7 @@ import {ActivatedRoute} from "@angular/router";
<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="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>
</ul>
`
@ -25,7 +26,7 @@ export class AdminTabsComponent implements OnInit {
@Input()
public user: User;
@Input()
public tab: "portal" | "page" | "entity" | "menu" | "class" | "customization" = 'page';
public tab: "portal" | "page" | "entity" | "menu" | "class" | "customization" | "template" = 'page';
private subscriptions: any[] = [];
constructor(private route: ActivatedRoute, private userManagementService: UserManagementService) {

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