From d0b4fa7750a8dde3cfa6b5b81c18302380e10c35 Mon Sep 17 00:00:00 2001 From: argirok Date: Fri, 19 Jan 2024 10:53:17 +0200 Subject: [PATCH] [plugins-functionality | WIP] : add component preview when managing plugins, add edit inside plugin preview, add plugin wrapper --- .../plugin-openaire-products.component.ts | 105 +++++++++++++++++ .../plugin-openaire-products.module.ts | 25 ++++ .../plugin-results-numbers.component.ts | 94 +++++++++++++++ .../plugin-results-numbers.module.ts | 24 ++++ .../components/test/plugin-test.component.ts | 71 +++++++++++ .../components/test/plugin-test.module.ts | 25 ++++ dashboard/plugins/plugins.component.html | 52 +++++---- dashboard/plugins/plugins.component.ts | 110 ++++++++++-------- dashboard/plugins/plugins.module.ts | 3 +- .../templates/pluginTemplates.component.html | 61 +++++++--- .../templates/pluginTemplates.component.ts | 52 ++++++--- .../templates/pluginTemplates.module.ts | 7 +- .../plugins/utils/base-plugin.component.ts | 60 ++++++++++ .../utils/plugin-field-edit.component.ts | 52 +++++++++ .../plugins/utils/plugin-field-edit.module.ts | 20 ++++ dashboard/plugins/wrapper/edit-plugin.css | 9 ++ .../wrapper/plugin-wrapper.component.ts | 39 +++++++ .../plugins/wrapper/plugin-wrapper.module.ts | 20 ++++ utils/entities/adminTool/plugin.ts | 19 ++- utils/entities/adminTool/pluginTemplate.ts | 24 +--- 20 files changed, 744 insertions(+), 128 deletions(-) create mode 100644 dashboard/plugins/components/openaireProducts/plugin-openaire-products.component.ts create mode 100644 dashboard/plugins/components/openaireProducts/plugin-openaire-products.module.ts create mode 100644 dashboard/plugins/components/results-numbers/plugin-results-numbers.component.ts create mode 100644 dashboard/plugins/components/results-numbers/plugin-results-numbers.module.ts create mode 100644 dashboard/plugins/components/test/plugin-test.component.ts create mode 100644 dashboard/plugins/components/test/plugin-test.module.ts create mode 100644 dashboard/plugins/utils/base-plugin.component.ts create mode 100644 dashboard/plugins/utils/plugin-field-edit.component.ts create mode 100644 dashboard/plugins/utils/plugin-field-edit.module.ts create mode 100644 dashboard/plugins/wrapper/edit-plugin.css create mode 100644 dashboard/plugins/wrapper/plugin-wrapper.component.ts create mode 100644 dashboard/plugins/wrapper/plugin-wrapper.module.ts diff --git a/dashboard/plugins/components/openaireProducts/plugin-openaire-products.component.ts b/dashboard/plugins/components/openaireProducts/plugin-openaire-products.component.ts new file mode 100644 index 00000000..df6d312b --- /dev/null +++ b/dashboard/plugins/components/openaireProducts/plugin-openaire-products.component.ts @@ -0,0 +1,105 @@ +import {Component} from '@angular/core'; +import {PluginBaseComponent, PluginEditEvent} from "../../utils/base-plugin.component"; +import {HttpClient} from "@angular/common/http"; + +export class PluginOpenAIREProducts{ + title:string ="OpenAIRE services for your community"; + serviceIds = {"zenodo":true,"graph":true,"explore":true}; + constructor() { + } +} +@Component({ + selector: 'plugin-openaire-products', + template: ` +
+
+ + + + +

+ {{pluginObject && pluginObject.title?pluginObject.title:pluginDefaultObject.title}}

+
+
+
+ + + +
+ +
+
+ +
+
+
{{service.name}}
+
{{service.tagline}}
+
+ Read more + +
+ + +
+
+
+
+
+
+
+
+
+ +
+ + `, + + +}) +export class PluginOpenaireProductsComponent extends PluginBaseComponent{ + services = []; + excludedServiceIds = ["openaire_login","research_community_dashboard"] + get pluginObject():PluginOpenAIREProducts{ + return this.plugin?this.plugin.object:null; + } + get pluginDefaultObject():PluginOpenAIREProducts{ + return this.pluginTemplate?this.pluginTemplate.object:null; + } + constructor(http:HttpClient) { + super() + this.subscriptions.push(http.get("https://explore.openaire.eu/cache/get?url="+ encodeURIComponent("https://catalogue.openaire.eu/api/catalogue-resources?from=0&quantity=100&order=asc&orderField=name")).subscribe(res =>{ + console.log(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); + })) + + } + ngOnInit(): void { + if(this.pluginTemplate && !this.pluginDefaultObject){ + this.pluginTemplate.object = new PluginOpenAIREProducts(); + } + } + + + serviceChanged(id,$event:PluginEditEvent){ + if(this.editTemplate){ + this.pluginTemplate.object.serviceIds[id]=$event.value; + $event.value =this.pluginTemplate.object.serviceIds; + }else{ + if(!this.plugin.object){ + this.plugin.object =this.pluginDefaultObject? Object.assign(this.pluginDefaultObject): new PluginOpenAIREProducts(); + } + console.log(this.plugin.object,this.plugin.object.serviceIds) + this.plugin.object.serviceIds[id]=$event.value; + $event.value =this.plugin.object.serviceIds; + } + + this.valuesChanged.emit($event) + } +} diff --git a/dashboard/plugins/components/openaireProducts/plugin-openaire-products.module.ts b/dashboard/plugins/components/openaireProducts/plugin-openaire-products.module.ts new file mode 100644 index 00000000..af6231f1 --- /dev/null +++ b/dashboard/plugins/components/openaireProducts/plugin-openaire-products.module.ts @@ -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([]) + } +} diff --git a/dashboard/plugins/components/results-numbers/plugin-results-numbers.component.ts b/dashboard/plugins/components/results-numbers/plugin-results-numbers.component.ts new file mode 100644 index 00000000..56310258 --- /dev/null +++ b/dashboard/plugins/components/results-numbers/plugin-results-numbers.component.ts @@ -0,0 +1,94 @@ +import {Component, Input, OnInit} from '@angular/core'; +import {Plugin} from "../../../../utils/entities/adminTool/plugin"; +import {PluginTemplate} from "../../../../utils/entities/adminTool/pluginTemplate"; +import {SearchResearchResultsService} from "../../../../services/searchResearchResults.service"; +import {FetchResearchResults} from "../../../../utils/fetchEntitiesClasses/fetchResearchResults.class"; +import {EnvProperties} from "../../../../utils/properties/env-properties"; +import { properties } from 'src/environments/environment'; +import {RouterHelper} from "../../../../utils/routerHelper.class"; +import {OpenaireEntities} from "../../../../utils/properties/searchFields"; +import {PluginBaseComponent} from "../../utils/base-plugin.component"; +export class PluginResultsNumbers{ + publicationsOnOff:boolean; + datasetsOnOff:boolean; + softwareOnOff:boolean; + otherOnOff:boolean; +} +@Component({ + selector: 'plugin-results-numbers', + template: ` +
+ + +
+ + ` +}) +export class PluginResultsNumbersComponent extends PluginBaseComponent{ + get pluginObject():PluginResultsNumbers{ + return this.plugin.object; + } + get pluginDefaultObject():PluginResultsNumbers{ + return this.pluginTemplate.object; + } + // Variables for publications, research data, projects, content providers, related content providers tabs + public fetchPublications: FetchResearchResults; + public fetchDatasets: FetchResearchResults; + public fetchSoftware: FetchResearchResults; + public fetchOrps: FetchResearchResults; + public fetchFeaturedDatasets: FetchResearchResults; + searchLinkToResults: string = null; + properties: EnvProperties = properties; + public routerHelper: RouterHelper = new RouterHelper(); + openaireEntities= OpenaireEntities; + + constructor(private _searchResearchResultsService: SearchResearchResultsService,) { + super(); + this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService); + this.fetchDatasets = new FetchResearchResults(this._searchResearchResultsService); + this.fetchSoftware = new FetchResearchResults(this._searchResearchResultsService); + this.fetchOrps = new FetchResearchResults(this._searchResearchResultsService); + this.fetchFeaturedDatasets = new FetchResearchResults(this._searchResearchResultsService); + } + ngOnInit(): void { + this.searchLinkToResults = this.properties.searchLinkToResults; + + } + + public getParamsForSearchLink(type: string = "") { + if (type) { + return this.routerHelper.createQueryParams(['type', 'qf', 'sortBy'], [type, 'false', 'resultdateofacceptance,descending']); + } else { + return {}; + } + } +} diff --git a/dashboard/plugins/components/results-numbers/plugin-results-numbers.module.ts b/dashboard/plugins/components/results-numbers/plugin-results-numbers.module.ts new file mode 100644 index 00000000..e59df0cf --- /dev/null +++ b/dashboard/plugins/components/results-numbers/plugin-results-numbers.module.ts @@ -0,0 +1,24 @@ +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 {PluginResultsNumbersComponent} from "./plugin-results-numbers.component"; +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"; + +@NgModule({ + imports: [ + CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule + ], + providers:[PluginsService], + declarations: [PluginResultsNumbersComponent], + exports: [PluginResultsNumbersComponent] +}) +export class PluginResultsNumbersModule { + constructor(private iconsService: IconsService) { + this.iconsService.registerIcons([]) + } +} diff --git a/dashboard/plugins/components/test/plugin-test.component.ts b/dashboard/plugins/components/test/plugin-test.component.ts new file mode 100644 index 00000000..80664fb8 --- /dev/null +++ b/dashboard/plugins/components/test/plugin-test.component.ts @@ -0,0 +1,71 @@ +import {Component} from '@angular/core'; +import {PluginBaseComponent} from "../../utils/base-plugin.component"; + +export class PluginTest{ + title:string ="Test Plugin"; + description: string = "Lorem ipsum"; + numberOn:boolean = true; + constructor() { + console.log(this) + } +} +@Component({ + selector: 'plugin-test', + template: ` + +
+
+ + + + +

+ {{pluginObject && pluginObject.title?pluginObject.title:pluginDefaultObject.title}}

+ + +
+
+ + + + +

+ {{pluginObject && pluginObject.description?pluginObject.description:pluginDefaultObject.description}}

+
+
+ + + + +

58K

+
+ +
+ + `, + + +}) +export class PluginTestComponent extends PluginBaseComponent{ + + get pluginObject():PluginTest{ + return this.plugin?this.plugin.object:null; + } + get pluginDefaultObject():PluginTest{ + return this.pluginTemplate?this.pluginTemplate.object:null; + } + constructor() { + super() + + } + ngOnInit(): void { + if(this.pluginTemplate && !this.pluginDefaultObject){ + this.pluginTemplate.object = new PluginTest(); + } + } + +} diff --git a/dashboard/plugins/components/test/plugin-test.module.ts b/dashboard/plugins/components/test/plugin-test.module.ts new file mode 100644 index 00000000..ee15806f --- /dev/null +++ b/dashboard/plugins/components/test/plugin-test.module.ts @@ -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 {PluginTestComponent} from "./plugin-test.component"; +import {PluginFieldEditModule} from "../../utils/plugin-field-edit.module"; + +@NgModule({ + imports: [ + CommonModule, RouterModule, FormsModule, IconsModule, NumberRoundModule, SearchResearchResultsServiceModule, PluginFieldEditModule + ], + providers:[PluginsService], + declarations: [PluginTestComponent], + exports: [PluginTestComponent] +}) +export class PluginTestModule { + constructor(private iconsService: IconsService) { + this.iconsService.registerIcons([]) + } +} diff --git a/dashboard/plugins/plugins.component.html b/dashboard/plugins/plugins.component.html index e3719676..cb51ea42 100644 --- a/dashboard/plugins/plugins.component.html +++ b/dashboard/plugins/plugins.component.html @@ -42,13 +42,13 @@
-
+
@@ -74,20 +74,21 @@
{{check.template.description}}
+ - + + + + + + +
Placement: {{check.plugin.placement}}
-
+
@@ -114,7 +115,8 @@ -
+ +
-
+ + <!– –> Select Template
@@ -177,7 +179,7 @@
-
+ -->
@@ -185,19 +187,21 @@
{{selectedTemplate.name}}
{{selectedTemplate.description}}
-
+ +
-
Plugin Fields
+
Plugin settings
-
-
-
+
+
-
+
{ this.portal = (this.route.snapshot.data.portal) ? this.route.snapshot.data.portal : this.route.snapshot.params[this.route.snapshot.data.param]; - this.templateView = this.route.snapshot.data['templateView'] + // this.templateView = this.route.snapshot.data['templateView'] this.selectedCommunityPid = params.community; - this.templateCode = params['templateCode']; + /*this.templateCode = params['templateCode']; if(this.templateView && this.templateCode){ this.getTemplateAndPlugins(); } if(this.templateView && !this.templateCode){ this._router.navigate(['../..'], {relativeTo: this.route}); - } + }*/ this.subscriptions.push(this.route.queryParams.subscribe(params => { HelperFunctions.scroll(); this.selectedPageId = params['pageId']; @@ -167,33 +168,18 @@ export class PluginsComponent implements OnInit { this.checkboxes = []; let self = this; - this.plugins.forEach(_ => { - self.checkboxes.push({plugin: _, checked: false, template: this.getTemplateByCode(_.code)}); - }); - - this.showLoading = false; - }, - error => this.handleError('System error retrieving plugins', error))); - - }, - error => this.handleError('System error retrieving templates', error))); - } - getTemplateAndPlugins(){ - - this.showLoading = true; - this.subscriptions.push(this._pluginsService.getPluginTemplate(this.properties.adminToolsAPIURL, this.templateCode).subscribe( - template => { - this.template = template; - this.pluginTemplates = [template] - - this.subscriptions.push(this._pluginsService.getPluginsByTemplatesCode(this.properties.adminToolsAPIURL,"", this.template.code).subscribe( - plugins => { - this.plugins = plugins; - this.checkboxes = []; - - let self = this; - this.plugins.forEach(_ => { - self.checkboxes.push({plugin: _, checked: false, template: this.template}); + this.pluginTemplates.forEach(_ => { + let plugin:Plugin = null; + for(let pl of plugins){ + if (pl.code == _.code){ + plugin = pl; + } + } + if(!plugin){ + plugin = new Plugin(this.selectedPageId, this.selectedCommunityPid,_); + this.plugins.push(plugin); + } + self.checkboxes.push({plugin: plugin, checked: false, template: _}); }); this.showLoading = false; @@ -203,6 +189,31 @@ export class PluginsComponent implements OnInit { }, error => this.handleError('System error retrieving templates', error))); } + // getTemplateAndPlugins(){ + // + // this.showLoading = true; + // this.subscriptions.push(this._pluginsService.getPluginTemplate(this.properties.adminToolsAPIURL, this.templateCode).subscribe( + // template => { + // this.template = template; + // this.pluginTemplates = [template] + // + // this.subscriptions.push(this._pluginsService.getPluginsByTemplatesCode(this.properties.adminToolsAPIURL,"", this.template.code).subscribe( + // plugins => { + // this.plugins = plugins; + // this.checkboxes = []; + // + // let self = this; + // this.plugins.forEach(_ => { + // self.checkboxes.push({plugin: _, checked: false, template: this.template}); + // }); + // + // this.showLoading = false; + // }, + // error => this.handleError('System error retrieving plugins', error))); + // + // }, + // error => this.handleError('System error retrieving templates', error))); + // } public toggleCheckBoxes(event) { this.checkboxes.forEach(_ => _.checked = event.target.checked); } @@ -246,7 +257,7 @@ export class PluginsComponent implements OnInit { } - public edit(plugin, template) { + public edit(plugin:Plugin, template:PluginTemplate) { this.editView = true; this.selectedPlugin = plugin; this.selectedTemplate = template; @@ -261,14 +272,15 @@ export class PluginsComponent implements OnInit { placement: this._fb.control(plugin.placement), order: this._fb.control(plugin.order), active: this._fb.control(plugin.active), - isPriorTo: this._fb.control(plugin.isPriorTo), - values: this._fb.array([]) + isPriorTo: this._fb.control(plugin.priorTo), + values: this._fb.array([]), + object: this._fb.group(plugin.object?plugin.object:this.selectedTemplate.object) }); - if (plugin.values) { - for (let attrKey of Object.keys(plugin.values)) { + 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.values[attrKey]) + 'value': this._fb.control(plugin.settingsValues[attrKey]?plugin.settingsValues[attrKey]:template.settings[attrKey].value) } )); } @@ -297,12 +309,13 @@ export class PluginsComponent implements OnInit { order: this._fb.control(""), active: this._fb.control(false), isPriorTo: this._fb.control(false), - values: this._fb.array([]) + values: this._fb.array([]), + object: this._fb.control(null) }); - for (let attrKey of Object.keys(this.selectedTemplate.attributes)) { + 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.attributes[attrKey].value ? this.selectedTemplate.attributes[attrKey].value : ""), + value: this._fb.control(this.selectedTemplate.settings[attrKey].value ? this.selectedTemplate.settings[attrKey].value : ""), })); } @@ -314,9 +327,9 @@ export class PluginsComponent implements OnInit { this.showLoading = true; let plugin: Plugin = this.templateForm.getRawValue(); // template.pages = this.pagesCtrl.getRawValue().map(page => page._id?page._id:page); - plugin.values = new Map(); + plugin.settingsValues = new Map(); for (let fields of this.templateForm.getRawValue().values) { - plugin.values[fields.key] = fields.value; + plugin.settingsValues[fields.key] = fields.value; } let update = (plugin._id ) ? true : false; console.log("update:" + update); @@ -368,10 +381,10 @@ export class PluginsComponent implements OnInit { public filterPlugins(plugin: Plugin, template: PluginTemplate): boolean { let values =[]; - for(let key of this.getKeys(plugin.values)){ - values.push(plugin.values[key]); + for(let key of this.getKeys(plugin.settingsValues)){ + values.push(plugin.settingsValues[key]); } - return this.searchText.toString() == '' || (plugin.code + ' ' +values.join(' ') + template.name + ' ' + template.description).match(this.searchText) != null; + return this.searchText.toString() == '' || (plugin.code + ' ' +values.join(' ') + (template?(template.name + ' ' +template.description):'')).match(this.searchText) != null; } @@ -442,7 +455,7 @@ export class PluginsComponent implements OnInit { } getKeys(obj) { - return Object.keys(obj); + return obj?Object.keys(obj):[]; } reset() { @@ -467,5 +480,10 @@ export class PluginsComponent implements OnInit { error => this.handleUpdateError('System error changing the status of Plugin', error) )); } - + pluginFieldChanged($event:PluginEditEvent){ + let object = this.templateForm.get("object").getRawValue(); + object[$event.field]=$event.value; + this.templateForm.get("object").setValue(object); + this.templateForm.markAsDirty(); + } } diff --git a/dashboard/plugins/plugins.module.ts b/dashboard/plugins/plugins.module.ts index 81cd08d3..2b181240 100644 --- a/dashboard/plugins/plugins.module.ts +++ b/dashboard/plugins/plugins.module.ts @@ -23,13 +23,14 @@ 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"; @NgModule({ imports: [ CommonModule, RouterModule, FormsModule, AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, MatAutocompleteModule, MatFormFieldModule, MatChipsModule, MatCheckboxModule, AdminTabsModule, PageContentModule, PluginsRoutingModule, SearchInputModule, IconsModule, LoadingModule, CKEditorModule, - MatSlideToggleModule + MatSlideToggleModule, PluginWrapperModule ], providers:[PluginsService], declarations: [PluginsComponent], diff --git a/dashboard/plugins/templates/pluginTemplates.component.html b/dashboard/plugins/templates/pluginTemplates.component.html index 3c1aa548..2c7b62b2 100644 --- a/dashboard/plugins/templates/pluginTemplates.component.html +++ b/dashboard/plugins/templates/pluginTemplates.component.html @@ -44,16 +44,21 @@ name="pagescb[]" value="{{check.page._id}}" [(ngModel)]="check.checked">
-->
-
{{check.template.name}}
+ + +
Pages: {{getPagesAsString(check.template.pages)}}
-
+
Placements: {{check.template.placements.join(", ")}}
Portal type: {{check.template.portalType}}
+
+ Plan: {{check.template.plan}} +
{{check.template.description}}
@@ -63,18 +68,18 @@