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, Validators } from "@angular/forms"; import {CheckPage, 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 {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 template = CKEDITOR.template; import {PluginEditEvent} from "./utils/base-plugin.component"; @Component({ selector: 'plugins', templateUrl: './plugins.component.html', }) export class PluginsComponent implements OnInit { @ViewChild('deleteModal') deleteModal: AlertModal; private selectedId: string; public checkboxes: { plugin: Plugin; checked: boolean; template: PluginTemplate }[] = []; 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; public filterForm: UntypedFormGroup; private subscriptions: any[] = []; public allPages: Option[] = []; public attrTypeOptions: Option[] = [ {label: "Text", value: "text"}, {label: "HTML", value: "HTML"}, {label: "Boolean", value: "boolean"}, {label: "URL", value: "URL"}, ]; public placementsOptions: Option[] = [ {label: "Top", value: "top"}, {label: "Bottom", value: "bottom"}, {label: "Top Right", value: "top-right"}, {label: "Center", value: "center"}, {label: "Right", value: "right"}, {label: "Left", value: "left"}, ]; 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 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 | Plugins'); this.filterForm = this._fb.group({ keyword: [''], type: ['all', Validators.required] }); this.subscriptions.push(this.filterForm.get('keyword').valueChanges.subscribe(value => { this.searchText = new RegExp(value, 'i'); this.applyFilters(); })); 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.templateView = this.route.snapshot.data['templateView'] this.selectedCommunityPid = params.community; /*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']; 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(); } }); } getTemplateByCode(code) { for (let template of this.pluginTemplates) { if (template.code == code) { 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.checkboxes = []; let self = this; 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; }, 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.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); } public applyCheck(flag: boolean) { this.checkboxes.forEach(_ => _.checked = flag); } private deleteFromArray(id: string): void { let i = this.plugins.findIndex(_ => _._id == id); this.plugins.splice(i, 1); this.applyFilters(); } public confirmDelete(id: string) { this.selectedId = id; 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.selectedId, this.properties.adminToolsAPIURL).subscribe( _ => { this.deleteFromArray(this.selectedId); NotificationHandler.rise('Template have been successfully deleted'); this.showLoading = false; this._clearCacheService.clearCache("Template id deleted"); }, error => this.handleUpdateError('System error deleting the selected Template', error) )); } public edit(plugin:Plugin, template:PluginTemplate) { this.editView = true; this.selectedPlugin = plugin; this.selectedTemplate = template; this.index = this.plugins.findIndex(value => value._id === plugin._id); // this.formPages = plugin.pages; 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), code: this._fb.control(plugin.code, Validators.required), placement: this._fb.control(plugin.placement), order: this._fb.control(plugin.order), active: this._fb.control(plugin.active), isPriorTo: this._fb.control(plugin.priorTo), values: this._fb.array([]), object: this._fb.group(plugin.object?plugin.object:this.selectedTemplate.object) }); 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.placements[0]), order: this._fb.control(""), active: this._fb.control(false), isPriorTo: this._fb.control(false), values: this._fb.array([]), object: this._fb.control(null) }); 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() { this.showLoading = true; let plugin: Plugin = this.templateForm.getRawValue(); // template.pages = this.pagesCtrl.getRawValue().map(page => page._id?page._id:page); plugin.settingsValues = new Map(); for (let fields of this.templateForm.getRawValue().values) { plugin.settingsValues[fields.key] = fields.value; } let update = (plugin._id ) ? true : false; console.log("update:" + update); this.subscriptions.push(this._pluginsService.savePlugin(plugin, this.properties.adminToolsAPIURL).subscribe( saved => { this.savedSuccessfully(saved, update); NotificationHandler.rise('Plugin ' + this.selectedTemplate.name + ' has been successfully' + (update ? ' updated ' : ' created ') + ''); this._clearCacheService.clearCache("Plugin id saved"); this.editView = false; this.selectTemplateView = false; this.selectedTemplate = null; this.selectedPlugin = null; }, error => this.handleUpdateError("System error creating template", error) )); } public savedSuccessfully(plugin: Plugin, update: boolean) { if (update) { this.plugins[this.index] = plugin; } else { this.plugins.push(plugin); } this.applyFilters(); this.applyCheck(false); this.showLoading = false; } public applyFilters() { /* this.checkboxes = []; this.plugins.filter(item => this.filterByType(item)).forEach( item => this.checkboxes.push({plugin: item, checked: false}) ); this.checkboxes = this.checkboxes.filter(item => this.filter(item.plugin));*/ this.checkboxes = []; this.plugins.forEach(item => { let template = this.getTemplateByCode(item.code); if (this.filterPlugins(item, template)) { this.checkboxes.push({plugin: item, checked: false, template: template}); } }); } 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.code + ' ' +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.selectedPlugin, this.selectedTemplate) } else { this.newPlugin(this.selectedTemplate) } } public togglePlugin(status: boolean, id: string) { this.subscriptions.push(this._pluginsService.togglePages(id, status, this.properties.adminToolsAPIURL).subscribe( () => { let i = this.checkboxes.findIndex(_ => _.plugin._id == id); this.checkboxes[i].plugin.active = status; this.applyCheck(false); this._clearCacheService.clearCache("Plugin's status changed"); this._clearCacheService.purgeBrowserCache("Plugin's status changed", this.portal); }, 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(); } }