[Library | Trunk]: Admin tools pages, fix modals and update behaviour

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-library/trunk/ng-openaire-library/src/app@60310 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
k.triantafyllou 2021-01-28 16:33:16 +00:00
parent 4e7ec1504e
commit 10cf547544
10 changed files with 478 additions and 559 deletions

View File

@ -96,15 +96,9 @@
</tr>
</tbody>
</table>
<div *ngIf="checkboxes.length==0" class="col-md-12">
<div class="uk-alert-warning uk-alert">No classes found</div>
</div>
<div class="uk-width-1-1 uk-flex uk-flex-center ">
<div class="uk-width-small uk-button uk-button-default" (click)="newDivId()">
<i class="" uk-icon="plus"></i>
</div>
</div>
</div>
</div>
</div>
@ -112,53 +106,18 @@
</div>
</div>
</div>
<modal-alert #AlertModalSaveDivId (alertOutput)="divIdSaveConfirmed($event)"
[okDisabled]="myForm && (myForm.invalid || !myForm.dirty)">
<modal-alert #editModal (alertOutput)="divIdSaveConfirmed($event)"
[okDisabled]="classForm && (classForm.invalid || !classForm.dirty)">
<div *ngIf="modalErrorMessage" class="uk-alert-danger" uk-alert aria-hidden="true">{{ modalErrorMessage }}</div>
<form [formGroup]="myForm">
<div dashboard-input class="uk-margin-small-left" [formInput]="myForm.get('name')"
type="text"
label="Class Name">
<form *ngIf="classForm" [formGroup]="classForm" class="uk-grid uk-child-width-1-1" uk-grid>
<div dashboard-input [formInput]="classForm.get('name')"
type="text" label="Class Name" placeholder="Write a name">
</div>
<mat-form-field class="example-chip-list uk-width-1-1 uk-margin-small-left">
<mat-chip-list #chipList aria-label="Page selection">
<mat-chip
*ngFor="let page of selectedPages"
[selectable]="true"
[removable]="true">
{{page.name}}
<span (click)="remove(page)"
class=" notranslate mat-chip-remove mat-chip-trailing-icon " uk-icon="trash"></span>
</mat-chip>
<input placeholder="Add in pages..." #PageInput
[formControl]="pageSearchCtrl" [matAutocomplete]="auto" [matChipInputFor]="chipList">
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let page of filteredPages| async" [value]="page">
{{page.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div [ngClass]="{'has-error':!myForm.controls.portalType.valid && myForm.controls.portalType.dirty}"
class="form-group" uk-grid>
<div class="uk-width-1-1 uk-margin-small-bottom uk-text-bold uk-form-label">
Class exists in:
</div>
<div class="uk-child-width-1-2 uk-grid">
<span *ngFor="let option of portalUtils.portalTypes" class="radio ">
<span class="uk-margin-small-right" style="font-weight: normal;">{{option.label}}</span>
<input type="radio" [value]="option.value" formControlName="portalType">
</span>
</div>
<div dashboard-input [formInput]="classForm.get('pages')" placeholder="Add a page"
type="chips" [options]="allPages" label="Pages" chipLabel="name">
</div>
<input type="hidden" formControlName="_id">
<div dashboard-input type="select" label="Portal Type" placeholder="Choose a type"
[formInput]="classForm.get('portalType')" [options]="portalUtils.portalTypes"></div>
</form>
</modal-alert>
<modal-alert #AlertModalDeleteDivIds (alertOutput)="confirmedDeleteDivIds($event)"></modal-alert>
<modal-alert #deleteModal (alertOutput)="confirmedDeleteDivIds($event)"></modal-alert>

View File

@ -1,7 +1,7 @@
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {HelpContentService} from "../../services/help-content.service";
import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {FormArray, FormBuilder, FormGroup, Validators} from "@angular/forms";
import {CheckDivId, DivId} from "../../utils/entities/adminTool/divId";
import {Page} from "../../utils/entities/adminTool/page";
import {EnvProperties} from '../../utils/properties/env-properties';
@ -9,12 +9,11 @@ import {EnvProperties} from '../../utils/properties/env-properties';
import {Session} from '../../login/utils/helper.class';
import {LoginErrorCodes} from '../../login/utils/guardHelper.class';
import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {Observable, Subscriber} from "rxjs";
import {map, startWith} from "rxjs/operators";
import {MatAutocompleteSelectedEvent, MatChipInputEvent} from "@angular/material";
import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {PortalUtils} from "../portal/portalHelper";
import {CheckPortal, Portal} from "../../utils/entities/adminTool/portal";
import {AlertModal} from "../../utils/modal/alert";
import {Option} from "../../sharedComponents/input/input.component";
@Component({
selector: 'divIds',
@ -22,34 +21,31 @@ import {CheckPortal, Portal} from "../../utils/entities/adminTool/portal";
})
export class DivIdsComponent implements OnInit {
@ViewChild('AlertModalSaveDivId') alertModalSaveDivId;
@ViewChild('AlertModalDeleteDivIds') alertModalDeleteDivIds;
@ViewChild('editModal') editModal: AlertModal;
@ViewChild('deleteModal') deleteModal: AlertModal;
private selectedDivIds: string[] = [];
public checkboxes: CheckDivId[] = [];
public divIds: DivId[] = [];
public myForm: FormGroup;
public pageSearchCtrl: FormControl;
public classForm: FormGroup;
public pagesCtrl: FormArray;
private searchText: RegExp = new RegExp('');
public keyword: string = "";
public properties: EnvProperties = null;
public properties: EnvProperties = properties;
public formPages: Page[] = [];
public showLoading: boolean = true;
public errorMessage: string = '';
public updateErrorMessage: string = '';
public modalErrorMessage: string = '';
public filterForm: FormGroup;
private subscriptions: any[] = [];
public allPages: Page[] = [];
filteredPages: Observable<Page[]>;
public allPages: Option[] = [];
@ViewChild('PageInput') pageInput: ElementRef<HTMLInputElement>;
selectedPages: Page[] = [];
selectedCommunityPid = null;
public portalUtils:PortalUtils = new PortalUtils();
private index: number;
ngOnInit() {
this.filterForm = this._fb.group({
keyword: [''],
@ -60,15 +56,6 @@ export class DivIdsComponent implements OnInit {
this.subscriptions.push(this.filterForm.get('type').valueChanges.subscribe(value => {
this.applyTypeFilter();
}));
this.pageSearchCtrl = this._fb.control('');
this.pagesCtrl = this._fb.array([]);
this.myForm = this._fb.group({
_id: '',
name: ['', Validators.required],
pages: this.pagesCtrl,
portalType: ['', Validators.required]
});
this.properties = properties;
this.getDivIds();
this.subscriptions.push(this.route.queryParams.subscribe(params => {
HelperFunctions.scroll();
@ -138,9 +125,11 @@ export class DivIdsComponent implements OnInit {
private deleteDivIdsFromArray(ids: string[]): void {
for (let id of ids) {
let i = this.checkboxes.findIndex(_ => _.divId._id == id);
this.checkboxes.splice(i, 1);
let i = this.divIds.findIndex(_ => _._id == id);
this.divIds.splice(i, 1);
}
this.applyTypeFilter();
this.applyFilter();
}
public confirmDeleteDivId(id: string) {
@ -162,12 +151,12 @@ export class DivIdsComponent implements OnInit {
}
});
} else {
this.alertModalDeleteDivIds.cancelButton = true;
this.alertModalDeleteDivIds.okButton = true;
this.alertModalDeleteDivIds.alertTitle = "Delete Confirmation";
this.alertModalDeleteDivIds.message = "Are you sure you want to delete the selected class(es)?";
this.alertModalDeleteDivIds.okButtonText = "Yes";
this.alertModalDeleteDivIds.open();
this.deleteModal.cancelButton = true;
this.deleteModal.okButton = true;
this.deleteModal.alertTitle = "Delete Confirmation";
this.deleteModal.message = "Are you sure you want to delete the selected class(es)?";
this.deleteModal.okButtonText = "Yes";
this.deleteModal.open();
}
}
@ -194,44 +183,38 @@ export class DivIdsComponent implements OnInit {
public editDivId(i: number) {
let divId: DivId = this.checkboxes[i].divId;
this.index = this.divIds.findIndex(value => value._id === divId._id);
this.formPages = <Page[]>divId.pages;
this.pagesCtrl = this._fb.array([]);
this.myForm = this._fb.group({
_id: divId._id,
name: [divId.name,Validators.required],
this.pagesCtrl = this._fb.array([], Validators.required);
this.classForm = this._fb.group({
_id: this._fb.control(divId._id),
name: this._fb.control(divId.name, Validators.required),
pages: this.pagesCtrl,
portalType: [divId.portalType, Validators.required]
portalType: this._fb.control(divId.portalType, Validators.required)
});
this.myForm.controls['portalType'].disable();
this.classForm.get('portalType').disable();
for(let i = 0; i < divId.pages.length; i++) {
this.pagesCtrl.push(this._fb.control(divId.pages[i]));
}
this.filteredPages = this.pageSearchCtrl.valueChanges.pipe(startWith(''),
map(page => this._filter(page)));
this.selectedPages = JSON.parse(JSON.stringify(divId.pages));
this.divIdsModalOpen(this.alertModalSaveDivId, "", "Save Changes");
this.divIdsModalOpen("Edit class", "Save Changes");
}
public newDivId() {
this.myForm.controls['portalType'].enable();
this.pagesCtrl = this._fb.array([]);
this.myForm = this._fb.group({
_id: '',
name: ['', Validators.required],
this.pagesCtrl = this._fb.array([], Validators.required);
if(this.classForm) {
this.classForm.get('portalType').enable();
}
this.classForm = this._fb.group({
_id: this._fb.control(null),
name: this._fb.control('', Validators.required),
pages: this.pagesCtrl,
//openaire: this._fb.control(true),
portalType: ['', Validators.required]
portalType: this._fb.control('', Validators.required)
});
this.filteredPages = this.pageSearchCtrl.valueChanges.pipe(startWith(''),
map(page => this._filter(page)));
this.modalErrorMessage = "";
this.selectedPages = [];
this.divIdsModalOpen(this.alertModalSaveDivId, "", "Save");
this.divIdsModalOpen("Create class", "Create");
}
private divIdsModalOpen(modal: any, title: string, yesBtn: string) {
private divIdsModalOpen(title: string, yesBtn: string) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
queryParams: {
@ -240,11 +223,12 @@ export class DivIdsComponent implements OnInit {
}
});
} else {
modal.cancelButton = true;
modal.okButton = true;
modal.alertTitle = title;
modal.okButtonText = yesBtn;
modal.open();
this.editModal.cancelButton = true;
this.editModal.okButton = true;
this.editModal.okButtonLeft = false;
this.editModal.alertTitle = title;
this.editModal.okButtonText = yesBtn;
this.editModal.open();
}
}
@ -257,20 +241,17 @@ export class DivIdsComponent implements OnInit {
}
});
} else {
console.log(this.myForm.value)
if (this.myForm.value['_id'].length == 0) {
this.myForm.controls['portalType'].enable();
if (!this.classForm.value._id) {
this.modalErrorMessage = "";
this.subscriptions.push(this._helpContentService.saveDivId(<DivId>this.myForm.value, this.properties.adminToolsAPIURL).subscribe(
this.subscriptions.push(this._helpContentService.saveDivId(<DivId>this.classForm.value, this.properties.adminToolsAPIURL).subscribe(
divId => {
this.divIdSavedSuccessfully(divId);
},
error => this.handleUpdateError("System error creating class", error)
));
} else {
this.subscriptions.push(this._helpContentService.updateDivId(<DivId>this.myForm.value, this.properties.adminToolsAPIURL).subscribe(
this.classForm.get('portalType').enable();
this.subscriptions.push(this._helpContentService.updateDivId(<DivId>this.classForm.value, this.properties.adminToolsAPIURL).subscribe(
divId => {
this.divIdUpdatedSuccessfully(divId);
},
@ -282,12 +263,16 @@ export class DivIdsComponent implements OnInit {
}
public divIdSavedSuccessfully(divId: DivId) {
this.checkboxes.push(<CheckDivId>{divId: divId, checked: false});
this.divIds.push(divId);
this.applyTypeFilter();
this.applyFilter();
this.applyCheck(false);
}
public divIdUpdatedSuccessfully(divId: DivId) {
this.checkboxes.find(checkItem => checkItem.divId._id == divId._id).divId = divId;
this.divIds[this.index] = divId;
this.applyTypeFilter();
this.applyFilter();
this.applyCheck(false);
}
@ -341,39 +326,16 @@ export class DivIdsComponent implements OnInit {
this.errorMessage = "";
this.subscriptions.push(this._helpContentService.getAllPages(this.properties.adminToolsAPIURL).subscribe(
pages => {
this.allPages = pages;
this.allPages = [];
pages.forEach(page => {
this.allPages.push({
label: page.name,
value: page
});
});
this.showLoading = false;
},
error => this.handleError('System error retrieving pages', error)
));
}
remove(page): void {
let index = this.selectedPages.indexOf(page);
if (index >= 0) {
this.selectedPages.splice(index, 1);
this.pagesCtrl.value.splice(index, 1);
this.pagesCtrl.markAsDirty();
}
}
selected(event: MatAutocompleteSelectedEvent): void {
let newPage = event.option.value;
if (this.selectedPages.indexOf(newPage) == -1) {
this.selectedPages.push(event.option.value);
this.pagesCtrl.push(this._fb.control(newPage));
this.pagesCtrl.markAsDirty();
}
this.pageInput.nativeElement.value = '';
this.pageSearchCtrl.setValue('');
}
private _filter(value: string): Page[] {
if (!value || value.length == 0) {
return this.allPages.slice();
}
const filterValue = value.toString().toLowerCase();
return this.allPages.filter(page => page.name.toLowerCase().indexOf(filterValue) != -1);
}
}

View File

@ -113,12 +113,7 @@
</tr>
</tbody>
</table>
<div class="uk-width-1-1 uk-flex uk-flex-center " *ngIf="isPortalAdministrator">
<div class="uk-width-small uk-button uk-button-default" (click)="newEntity()">
<i class="" uk-icon="plus"></i>
</div>
</div>
<div *ngIf="checkboxes.length==0" class="col-md-12">
<div *ngIf="checkboxes.length ==0 ">
<div class="uk-alert-warning" uk-alert>No entities found</div>
</div>
</div>
@ -129,24 +124,21 @@
</div>
</div>
<modal-alert #AlertModalSaveEntity (alertOutput)="entitySaveConfirmed($event)"
[okDisabled]="myForm && (myForm.invalid || !myForm.dirty)">
<modal-alert #editModal (alertOutput)="entitySaveConfirmed($event)"
[okDisabled]="entityForm && (entityForm.invalid || !entityForm.dirty)">
<div *ngIf="modalErrorMessage" class="uk-alert-danger" uk-alert aria-hidden="true">{{ modalErrorMessage }}</div>
<form [formGroup]="myForm">
<div dashboard-input class="uk-margin-small-left" [formInput]="myForm.controls.name"
type="text"
<form *ngIf="entityForm" [formGroup]="entityForm" class="uk-grid uk-child-width-1-1" uk-grid>
<div dashboard-input [formInput]="entityForm.get('name')"
type="text" placeholder="Write a name"
label="Entity Name">
</div>
<div dashboard-input class="uk-margin-small-left" [formInput]="myForm.controls.pid"
type="text"
<div dashboard-input [formInput]="entityForm.get('pid')"
type="text" placeholder="Write a pid"
label="Entity Pid">
</div>
<input type="hidden" formControlName="_id">
</form>
</modal-alert>
<modal-alert #AlertModalRelatedPages (alertOutput)="continueToggling($event)"></modal-alert>
<modal-alert #relatedPages (alertOutput)="continueToggling($event)"></modal-alert>
<modal-alert #AlertModalDeleteEntities (alertOutput)="confirmedDeleteEntities($event)"></modal-alert>
<modal-alert #deleteModal (alertOutput)="confirmedDeleteEntities($event)"></modal-alert>

View File

@ -1,17 +1,17 @@
import {Component, ViewChild, OnInit, ElementRef} from '@angular/core';
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {HelpContentService} from '../../services/help-content.service';
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {CheckEntity, Entity} from '../../utils/entities/adminTool/entity';
import {Portal} from '../../utils/entities/adminTool/portal';
import {EnvProperties} from '../../utils/properties/env-properties';
import {Session} from '../../login/utils/helper.class';
import {LoginErrorCodes} from '../../login/utils/guardHelper.class';
import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {UserManagementService} from '../../services/user-management.service';
import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {ConnectHelper} from "../../connect/connectHelper";
import {AlertModal} from "../../utils/modal/alert";
@Component({
selector: 'entities',
@ -20,15 +20,16 @@ import {ConnectHelper} from "../../connect/connectHelper";
export class EntitiesComponent implements OnInit {
@ViewChild('AlertModalSaveEntity') alertModalSaveEntity;
@ViewChild('AlertModalDeleteEntities') alertModalDeleteEntities;
@ViewChild('editModal') editModal: AlertModal;
@ViewChild('deleteModal') deleteModal: AlertModal;
@ViewChild('relatedPages') relatedPages: AlertModal;
private selectedEntities: string[] = [];
public checkboxes: CheckEntity[] = [];
public entities: Entity[] = [];
public myForm: FormGroup;
public entityForm: FormGroup;
private searchText: RegExp = new RegExp('');
public keyword = '';
@ -36,8 +37,6 @@ export class EntitiesComponent implements OnInit {
public communities: Portal[] = [];
public portal: string;
@ViewChild('AlertModalRelatedPages') alertModalRelatedPages;
public toggleIds: string[];
public toggleStatus: boolean;
public properties: EnvProperties = properties;
@ -49,6 +48,7 @@ export class EntitiesComponent implements OnInit {
public isPortalAdministrator = null;
public filterForm: FormGroup;
private subscriptions: any[] = [];
private index: number;
constructor(private element: ElementRef, private route: ActivatedRoute,
private _router: Router,
@ -61,13 +61,6 @@ export class EntitiesComponent implements OnInit {
keyword: [''],
status: ['all', Validators.required]
});
this.myForm = this._fb.group({
pid: ['', Validators.required],
name: ['', Validators.required],
isEnabled: '',
_id: ''
});
this.subscriptions.push(this.filterForm.get('keyword').valueChanges.subscribe(value => {
this.filterBySearch(value);
}));
@ -149,9 +142,10 @@ export class EntitiesComponent implements OnInit {
private deleteEntitiesFromArray(ids: string[]): void {
for (let id of ids) {
const i = this.checkboxes.findIndex(_ => _.entity._id === id);
this.checkboxes.splice(i, 1);
let i = this.entities.findIndex(_ => _._id == id);
this.entities.splice(i, 1);
}
this.applyFilter();
}
public confirmDeleteEntity(id: string) {
@ -173,12 +167,12 @@ export class EntitiesComponent implements OnInit {
this._router.navigate(['/user-info'],
{queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url}});
} else {
this.alertModalDeleteEntities.cancelButton = true;
this.alertModalDeleteEntities.okButton = true;
this.alertModalDeleteEntities.alertTitle = 'Delete Confirmation';
this.alertModalDeleteEntities.message = 'Are you sure you want to delete the selected entity(-ies)?';
this.alertModalDeleteEntities.okButtonText = 'Yes';
this.alertModalDeleteEntities.open();
this.deleteModal.cancelButton = true;
this.deleteModal.okButton = true;
this.deleteModal.alertTitle = 'Delete Confirmation';
this.deleteModal.message = 'Are you sure you want to delete the selected entity(-ies)?';
this.deleteModal.okButtonText = 'Yes';
this.deleteModal.open();
}
}
@ -202,36 +196,37 @@ export class EntitiesComponent implements OnInit {
public editEntity(i: number) {
const entity: Entity = this.checkboxes[i].entity;
this.myForm = this._fb.group({
name: [entity.name, Validators.required],
_id: entity._id,
pid: [entity.pid, Validators.required],
this.index = this.entities.findIndex(value => value._id === entity._id);
this.entityForm = this._fb.group({
name: this._fb.control(entity.name, Validators.required),
_id: this._fb.control(entity._id),
pid: this._fb.control(entity.pid, Validators.required)
});
this.modalErrorMessage = '';
this.entitiesModalOpen(this.alertModalSaveEntity, '', 'Save Changes');
this.entitiesModalOpen('Edit Entity', 'Save Changes');
}
public newEntity() {
this.myForm = this._fb.group({
pid: ['', Validators.required],
name: ['', Validators.required],
isEnabled: '',
_id: ''
this.entityForm = this._fb.group({
_id: this._fb.control(null),
name: this._fb.control('', Validators.required),
pid: this._fb.control('', Validators.required)
});
this.modalErrorMessage = '';
this.entitiesModalOpen(this.alertModalSaveEntity, '', 'Save');
this.entitiesModalOpen('Create Entity', 'Create');
}
private entitiesModalOpen(modal: any, title: string, yesBtn: string) {
private entitiesModalOpen(title: string, yesBtn: string) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'],
{queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url}});
} else {
modal.cancelButton = true;
modal.okButton = true;
modal.alertTitle = title;
modal.okButtonText = yesBtn;
modal.open();
this.editModal.cancelButton = true;
this.editModal.okButton = true;
this.editModal.okButtonLeft = false;
this.editModal.alertTitle = title;
this.editModal.okButtonText = yesBtn;
this.editModal.open();
}
}
@ -241,16 +236,16 @@ export class EntitiesComponent implements OnInit {
{queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url}});
} else {
this.modalErrorMessage = '';
if (this.myForm.getRawValue()['_id'].length > 0) {
if (this.entityForm.value._id) {
this._helpContentService.updateEntity(
<Entity>this.myForm.value, this.properties.adminToolsAPIURL).subscribe(
<Entity>this.entityForm.value, this.properties.adminToolsAPIURL).subscribe(
entity => {
this.entityUpdatedSuccessfully(entity);
},
error => this.handleUpdateError('System error updating entity', error)
);
} else {
this._helpContentService.saveEntity(<Entity>this.myForm.value, this.properties.adminToolsAPIURL).subscribe(
this._helpContentService.saveEntity(<Entity>this.entityForm.value, this.properties.adminToolsAPIURL).subscribe(
entity => {
this.entitySavedSuccessfully(entity);
},
@ -262,12 +257,14 @@ export class EntitiesComponent implements OnInit {
public entitySavedSuccessfully(entity: Entity) {
this.checkboxes.push(<CheckEntity>{entity: entity, checked: false});
this.entities.push(entity);
this.applyFilter();
this.applyCheck(false);
}
public entityUpdatedSuccessfully(entity: Entity) {
this.checkboxes.find(checkItem => checkItem.entity._id === entity._id).entity = entity;
this.entities[this.index] = entity;
this.applyFilter();
this.applyCheck(false);
}
@ -309,7 +306,7 @@ export class EntitiesComponent implements OnInit {
handleUpdateError(message: string, error) {
if (error == null) {
this.myForm = this._fb.group({
this.entityForm = this._fb.group({
pid: ['', Validators.required],
name: ['', Validators.required],
isEnabled: '',
@ -339,12 +336,12 @@ export class EntitiesComponent implements OnInit {
this._router.navigate(['/user-info'],
{queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url}});
} else {
this.alertModalRelatedPages.cancelButton = true;
this.alertModalRelatedPages.okButton = true;
this.alertModalRelatedPages.alertTitle = 'Warning';
this.alertModalRelatedPages.message = "This action will affect all search pages related to this entity! Pages' status will change to entity's status! Do you want to continue?";
this.alertModalRelatedPages.okButtonText = 'Yes';
this.alertModalRelatedPages.open();
this.relatedPages.cancelButton = true;
this.relatedPages.okButton = true;
this.relatedPages.alertTitle = 'Warning';
this.relatedPages.message = "This action will affect all search pages related to this entity! Pages' status will change to entity's status! Do you want to continue?";
this.relatedPages.okButtonText = 'Yes';
this.relatedPages.open();
}
}

View File

@ -121,15 +121,9 @@
</li>
</ul>
<div *ngIf="checkboxes.length==0" class="col-md-12">
<div *ngIf="checkboxes.length==0">
<div class="uk-alert-warning" uk-alert>No pages found</div>
</div>
<div *ngIf="isPortalAdministrator" class="uk-width-1-1 uk-flex uk-flex-center ">
<div class="uk-width-small uk-button uk-button-default" (click)="newPage()">
<i class="" uk-icon="plus"></i>
</div>
</div>
</div>
</div>
</div>
@ -137,85 +131,52 @@
</div>
</div>
<modal-alert #AlertModalSavePage (alertOutput)="pageSaveConfirmed($event)"
[okDisabled]="myForm && (myForm.invalid || !myForm.dirty)">
<modal-alert #editModal (alertOutput)="pageSaveConfirmed($event)"
[okDisabled]="pageForm && (pageForm.invalid || !pageForm.dirty)">
<div *ngIf="modalErrorMessage" class="uk-alert-danger" uk-alert aria-hidden="true">{{ modalErrorMessage }}</div>
<form [formGroup]="myForm">
<div dashboard-input class="uk-margin-small-left" [formInput]="myForm.get('route')"
type="text"
label="Page route">
<form *ngIf="pageForm" [formGroup]="pageForm" class="uk-grid uk-child-width-1-1" uk-grid>
<div dashboard-input [formInput]="pageForm.get('route')"
type="text" label="Page route" placeholder="Write a route">
</div>
<div dashboard-input class="uk-margin-small-left" [formInput]="myForm.get('name')"
type="text"
<div dashboard-input [formInput]="pageForm.get('name')"
type="text" placeholder="Write a name"
label="Page Name">
</div>
<div dashboard-input class="uk-margin-small-left" [formInput]="myForm.get('type')"
type="select"
<div dashboard-input [formInput]="pageForm.get('type')"
type="select" placeholder="Choose a page Type"
label="Type" [options]="typeOptions">
</div>
<mat-form-field class="example-chip-list uk-width-1-1 uk-margin-small-left">
<mat-chip-list #chipList aria-label="Page selection">
<mat-chip
*ngFor="let entity of selectedEntities"
[selectable]="true"
[removable]="true">
{{entity.name}}
<span (click)="remove(entity)"
class=" notranslate mat-chip-remove mat-chip-trailing-icon " uk-icon="trash"></span>
</mat-chip>
<input placeholder="Add in pages..." #PageInput
[formControl]="entitiesSearchCtrl" [matAutocomplete]="auto" [matChipInputFor]="chipList">
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let entity of filteredEntities| async" [value]="entity">
{{entity.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div dashboard-input [formInput]="pageForm.get('entities')" placeholder="Add an entity"
type="chips" [options]="allEntities" label="Entities" chipLabel="name">
</div>
<div dashboard-input type="select" label="Portal Type" placeholder="Choose a type"
[formInput]="pageForm.get('portalType')" [options]="portalUtils.portalTypes"></div>
<div class="form-group">
<label class="uk-text-danger uk-margin-small-bottom">
By disabling a position, all contents in this position will be deleted.
</label>
<div class="title"> Select if this page exists in:</div>
<div class=" uk-grid">
<span dashboard-input class="" [formInput]="myForm.get('top')"
<div class="uk-form-label uk-text-bold uk-margin-small-bottom"> Select if this page have helptext at: </div>
<div class="uk-grid uk-grid-small uk-child-width-1-4" uk-grid>
<div dashboard-input [formInput]="pageForm.get('top')"
type="checkbox"
label="Top">
</span>
<span dashboard-input class="uk-margin-small-left" [formInput]="myForm.get('right')"
</div>
<div dashboard-input [formInput]="pageForm.get('right')"
type="checkbox"
label="Right">
</span>
<span dashboard-input class="uk-margin-small-left" [formInput]="myForm.get('bottom')"
</div>
<div dashboard-input [formInput]="pageForm.get('bottom')"
type="checkbox"
label="Bottom">
</span>
<span dashboard-input class="uk-margin-small-left" [formInput]="myForm.get('left')"
</div>
<div dashboard-input [formInput]="pageForm.get('left')"
type="checkbox"
label="Left">
</span>
</div>
</div>
<label class="uk-text-danger">
By disabling a position, all contents in this position will be deleted.
</label>
</div>
<div [ngClass]="{'has-error':!myForm.controls.portalType.valid && myForm.controls.portalType.dirty}"
class="form-group">
<div class="uk-width-1-1 uk-margin-small-bottom uk-text-bold uk-form-label">
Page exists in:
</div>
<div class="uk-child-width-1-2 uk-grid">
<span *ngFor="let option of portalUtils.portalTypes" class="radio ">
<span class="uk-margin-small-right" style="font-weight: normal;">{{option.label}}</span>
<input type="radio" [value]="option.value" formControlName="portalType">
</span>
</div>
</div>
<input type="hidden" formControlName="_id">
</form>
</modal-alert>
<modal-alert #AlertModalDeletePages (alertOutput)="confirmedDeletePages($event)"></modal-alert>
<modal-alert #deleteModal (alertOutput)="confirmedDeletePages($event)"></modal-alert>

View File

@ -16,6 +16,8 @@ import {MatAutocompleteSelectedEvent} from "@angular/material";
import {PortalUtils} from "../portal/portalHelper";
import {properties} from "../../../../environments/environment";
import {ConnectHelper} from "../../connect/connectHelper";
import {Option} from "../../sharedComponents/input/input.component";
import {AlertModal} from "../../utils/modal/alert";
@Component({
selector: 'pages',
@ -23,35 +25,35 @@ import {ConnectHelper} from "../../connect/connectHelper";
})
export class PagesComponent implements OnInit {
@ViewChild('AlertModalSavePage') alertModalSavePage;
@ViewChild('AlertModalDeletePages') alertModalDeletePages;
@ViewChild('editModal') editModal: AlertModal;
@ViewChild('deleteModal') deleteModal: AlertModal;
private selectedPages: string[] = [];
public checkboxes: CheckPage[] = [];
public pages: Page[] = [];
public pageWithDivIds: string[] = [];
//public errorMessage: string;
public myForm: FormGroup;
public pageForm: FormGroup;
private searchText: RegExp = new RegExp('');
public keyword: string = '';
public portal: string;
public pagesType: string;
public properties: EnvProperties = null;
public properties: EnvProperties = properties;
public showLoading: boolean = true;
public errorMessage: string = '';
public updateErrorMessage: string = '';
public modalErrorMessage: string = '';
public isPortalAdministrator = null;
public filterForm: FormGroup;
public typeOptions = [{label: 'Search', value: 'search'}, {
public typeOptions = [{label: 'Search', value: 'search'}, {
label: 'Share',
value: 'share'
}, {label: 'Landing', value: 'landing'}, {label: 'HTML', value: 'html'}, {
@ -60,52 +62,35 @@ export class PagesComponent implements OnInit {
}, {label: 'Other', value: 'other'}];
public entitiesCtrl: FormArray;
@ViewChild('PageInput') pageInput: ElementRef<HTMLInputElement>;
public entitiesSearchCtrl: FormControl;
filteredEntities: Observable<Entity[]>;
selectedEntities: Entity[] = [];
allEntities: Entity[] = [];
allEntities: Option[] = [];
private subscriptions: any[] = [];
public portalUtils:PortalUtils = new PortalUtils();
public portalUtils: PortalUtils = new PortalUtils();
private index: number;
constructor(private element: ElementRef, private route: ActivatedRoute,
private _router: Router, private _helpContentService: HelpContentService,
private userManagementService: UserManagementService, private _fb: FormBuilder) {
}
ngOnInit() {
this.filterForm = this._fb.group({
this.filterForm = this._fb.group({
keyword: [''],
type: ['all', Validators.required]});
type: ['all', Validators.required]
});
this.subscriptions.push(this.filterForm.get('keyword').valueChanges.subscribe(value => {
this.filterBySearch(value);
}));
this.subscriptions.push(this.filterForm.get('type').valueChanges.subscribe(value => {
this.applyTypeFilter();
}));
this.entitiesSearchCtrl = this._fb.control('');
this.myForm = this._fb.group({
route: ['', Validators.required],
name: ['', Validators.required],
isEnabled: true,
portalType: ['', Validators.required],
top: true,
bottom: true,
left: true,
right: true,
type: ['', Validators.required],
entities: this.entitiesCtrl,
_id: '',
});
this.properties = properties;
this.subscriptions.push(this.route.queryParams.subscribe(params => {
this.pagesType = '';
if (params['type']) {
// this.pagesType = params['type'];
this.filterForm.get('type').setValue(params['type']);
}
this.portal = (this.route.snapshot.data.portal)?this.route.snapshot.data.portal:this.route.snapshot.params[this.route.snapshot.data.param];
if(this.portal === 'connect' || this.portal === 'explore') {
this.portal = (this.route.snapshot.data.portal) ? this.route.snapshot.data.portal : this.route.snapshot.params[this.route.snapshot.data.param];
if (this.portal === 'connect' || this.portal === 'explore') {
ConnectHelper.setPortalTypeFromPid(this.portal);
}
this.keyword = '';
@ -114,17 +99,23 @@ export class PagesComponent implements OnInit {
this.isPortalAdministrator = Session.isPortalAdministrator(user) && !this.portal;
}));
}));
this.subscriptions.push(this._helpContentService.getEntities(this.properties.adminToolsAPIURL).subscribe(
entities => {
this.allEntities = entities;
this.allEntities = [];
entities.forEach(entity => {
this.allEntities.push({
label: entity.name,
value: entity
});
});
this.showLoading = false;
},
error => this.handleError('System error retrieving pages', error)));
}
ngOnDestroy(): void {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
@ -134,7 +125,7 @@ export class PagesComponent implements OnInit {
}
});
}
getPages(portal: string) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
@ -147,9 +138,9 @@ export class PagesComponent implements OnInit {
this.showLoading = true;
this.updateErrorMessage = '';
this.errorMessage = '';
this.pageWithDivIds = [];
let parameters = '';
if (this.pagesType) {
parameters = '?page_type=' + this.pagesType;
@ -177,7 +168,7 @@ export class PagesComponent implements OnInit {
}
}
}
getPagesWithDivIds(portal: string) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
@ -195,18 +186,18 @@ export class PagesComponent implements OnInit {
error => this.handleError('System error retrieving information about pages\' classes', error)));
}
}
pagesReturned(pages: Page[]) {
this.pages = pages;
this.checkboxes = [];
if (pages) {
pages.forEach(_ => {
this.checkboxes.push(<CheckPage>{page: _, checked: false});
});
}
}
/*
getPortals() {
this._helpContentService.getCommunities(this.properties.adminToolsAPIURL).subscribe(
@ -219,40 +210,42 @@ export class PagesComponent implements OnInit {
error => this.handleError('System error retrieving communities', error));
}
*/
public toggleCheckBoxes(event) {
this.checkboxes.forEach(_ => _.checked = event.target.checked);
}
public applyCheck(flag: boolean) {
this.checkboxes.forEach(_ => _.checked = flag);
}
public getSelectedPages(): string[] {
return this.checkboxes.filter(page => page.checked == true).map(checkedPage => checkedPage.page).map(res => res._id);
}
private deletePagesFromArray(ids: string[]): void {
for (let id of ids) {
let i = this.checkboxes.findIndex(_ => _.page._id == id);
this.checkboxes.splice(i, 1);
let i = this.pages.findIndex(_ => _._id == id);
this.pages.splice(i, 1);
}
this.applyTypeFilter();
this.applyFilter();
}
public confirmDeletePage(id: string) {
//this.deleteConfirmationModal.ids = [id];
//this.deleteConfirmationModal.showModal();
this.selectedPages = [id];
this.confirmModalOpen();
}
public confirmDeleteSelectedPages() {
//this.deleteConfirmationModal.ids = this.getSelectedPages();
//this.deleteConfirmationModal.showModal();
this.selectedPages = this.getSelectedPages();
this.confirmModalOpen();
}
private confirmModalOpen() {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
@ -262,15 +255,15 @@ export class PagesComponent implements OnInit {
}
});
} else {
this.alertModalDeletePages.cancelButton = true;
this.alertModalDeletePages.okButton = true;
this.alertModalDeletePages.alertTitle = 'Delete Confirmation';
this.alertModalDeletePages.message = 'Are you sure you want to delete the selected page(s)?';
this.alertModalDeletePages.okButtonText = 'Yes';
this.alertModalDeletePages.open();
this.deleteModal.cancelButton = true;
this.deleteModal.okButton = true;
this.deleteModal.alertTitle = 'Delete Confirmation';
this.deleteModal.message = 'Are you sure you want to delete the selected page(s)?';
this.deleteModal.okButtonText = 'Yes';
this.deleteModal.open();
}
}
public confirmedDeletePages(data: any) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
@ -282,7 +275,7 @@ export class PagesComponent implements OnInit {
} else {
this.showLoading = true;
this.updateErrorMessage = '';
this.subscriptions.push(this._helpContentService.deletePages(this.selectedPages, this.properties.adminToolsAPIURL).subscribe(
_ => {
this.deletePagesFromArray(this.selectedPages);
@ -292,68 +285,55 @@ export class PagesComponent implements OnInit {
));
}
}
public editPage(i: number) {
this.entitiesCtrl = this._fb.array([]);
let page: Page = this.checkboxes[i].page;
this.myForm = this._fb.group({
route: [page.route, Validators.required],
name: [page.name, Validators.required],
isEnabled: page.isEnabled,
portalType: ['', Validators.required],
top: page.top,
bottom: page.bottom,
left: page.left,
right: page.right,
type: [page.type, Validators.required],
entities: this.entitiesCtrl,
_id: page._id,
this.index = this.pages.findIndex(value => value._id === page._id);
this.pageForm = this._fb.group({
_id: this._fb.control(page._id),
route: this._fb.control(page.route, Validators.required),
name: this._fb.control(page.name, Validators.required),
isEnabled: this._fb.control(page.isEnabled),
portalType: this._fb.control(page.portalType, Validators.required),
top: this._fb.control(page.top),
bottom: this._fb.control(page.bottom),
left: this._fb.control(page.left),
right: this._fb.control(page.right),
type: this._fb.control(page.type, Validators.required),
entities: this.entitiesCtrl
});
this.myForm.controls['portalType'].disable();
this.pageForm.get('portalType').disable();
for (let i = 0; i < page.entities.length; i++) {
this.entitiesCtrl.push(this._fb.control(page.entities[i]));
}
this.filteredEntities = this.entitiesSearchCtrl.valueChanges.pipe(startWith(''),
map(page => this._filter(page)));
this.selectedEntities = JSON.parse(JSON.stringify(page.entities));
this.modalErrorMessage = '';
this.pagesModalOpen(this.alertModalSavePage, '', 'Save changes');
this.pagesModalOpen('Edit Page', 'Save changes');
}
private _filter(value: string): Entity[] {
if (!value || value.length == 0) {
return this.allEntities.slice();
}
const filterValue = value.toString().toLowerCase();
return this.allEntities.filter(page => page.name.toLowerCase().indexOf(filterValue) != -1);
}
public newPage() {
this.myForm.controls['portalType'].enable();
if(this.pageForm) {
this.pageForm.get('portalType').enable();
}
this.entitiesCtrl = this._fb.array([]);
this.myForm = this._fb.group({
route: ['', Validators.required],
name: ['', Validators.required],
isEnabled: true,
portalType: ['', Validators.required],
top: true,
bottom: true,
left: true,
right: true,
type: [this.typeOptions[0].value, Validators.required],
entities: this._fb.array([]),
_id: '',
this.pageForm = this._fb.group({
_id: this._fb.control(null),
route: this._fb.control('', Validators.required),
name: this._fb.control('', Validators.required),
isEnabled: this._fb.control(true),
portalType: this._fb.control('', Validators.required),
top: this._fb.control(true),
bottom: this._fb.control(true),
left: this._fb.control(true),
right: this._fb.control(true),
type: this._fb.control(this.typeOptions[0].value, Validators.required),
entities: this.entitiesCtrl,
});
this.selectedEntities = [];
this.modalErrorMessage = '';
this.filteredEntities = this.entitiesSearchCtrl.valueChanges.pipe(startWith(''),
map(page => this._filter(page)));
this.pagesModalOpen(this.alertModalSavePage, '', 'Save');
this.pagesModalOpen('Create Page', 'Create');
}
private pagesModalOpen(modal: any, title: string, yesBtn: string) {
private pagesModalOpen(title: string, yesBtn: string) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
queryParams: {
@ -362,14 +342,15 @@ export class PagesComponent implements OnInit {
}
});
} else {
modal.cancelButton = true;
modal.okButton = true;
modal.alertTitle = title;
modal.okButtonText = yesBtn;
modal.open();
this.editModal.cancelButton = true;
this.editModal.okButton = true;
this.editModal.okButtonLeft = false;
this.editModal.alertTitle = title;
this.editModal.okButtonText = yesBtn;
this.editModal.open();
}
}
public pageSaveConfirmed(data: any) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
@ -379,84 +360,68 @@ export class PagesComponent implements OnInit {
}
});
} else {
console.log(this.myForm.value)
if (this.myForm.value['_id'].length == 0) {
this.myForm.controls['portalType'].enable();
if (!this.pageForm.value._id) {
this.modalErrorMessage = '';
this.subscriptions.push(this._helpContentService.savePage(<Page>this.myForm.value, this.properties.adminToolsAPIURL).subscribe(
this.subscriptions.push(this._helpContentService.savePage(<Page>this.pageForm.value, this.properties.adminToolsAPIURL).subscribe(
page => {
this.pageSavedSuccessfully(page, true);
},
error => this.handleUpdateError('System error creating page', error)
));
} else {
this.subscriptions.push(this._helpContentService.updatePage(<Page>this.myForm.value, this.properties.adminToolsAPIURL).subscribe(
this.pageForm.get('portalType').enable();
this.subscriptions.push(this._helpContentService.updatePage(<Page>this.pageForm.value, this.properties.adminToolsAPIURL).subscribe(
page => {
this.pageSavedSuccessfully(page, false);
},
error => this.handleUpdateError('System error updating page', error)
));
}
}
}
/* public pageUpdateConfirmed(data: any) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url}});
} else {
if (!this.myForm.valid) {
this.pagesModalOpen(this.alertModalSavePage, 'Update', 'Update Page');
this.modalErrorMessage = 'Please fill in all required fields marked with *';
} else {
this._helpContentService.updatePage(<Page>this.myForm.value, this.properties.adminToolsAPIURL).subscribe(
page => {
this.pageUpdatedSuccessfully(page);
},
error => this.handleUpdateError('System error updating page', error)
);
}
}
}*/
public pageSavedSuccessfully(page: Page, isNew: boolean) {
if (isNew) {
this.checkboxes.push(<CheckPage>{page: page, checked: false});
this.pages.push(page);
} else {
this.checkboxes.find(checkItem => checkItem.page._id == page._id).page = page;
this.pages[this.index] = page;
}
this.applyTypeFilter();
this.applyFilter();
this.applyCheck(false);
}
public filterBySearch(text: string) {
this.searchText = new RegExp(text, 'i');
this.applyFilter();
}
public applyFilter() {
this.checkboxes = [];
this.pages.filter(item => this.filterPages(item)).forEach(
_ => this.checkboxes.push(<CheckPage>{page: _, checked: false})
);
}
public applyTypeFilter() {
this.checkboxes = [];
this.pages.filter(item => this.filterByType(item)).forEach(
_ => this.checkboxes.push(<CheckPage>{page: _, checked: false})
);
}
public filterByType(page: Page): boolean {
let type = this.filterForm.get("type").value;
return type == "all" || (type == page.type);
return type == "all" || (type == page.type);
}
public filterPages(page: Page): boolean {
let textFlag = this.searchText.toString() == '' || (page.route + ' ' + page.name + ' ' + page.portalType).match(this.searchText) != null;
return textFlag;
}
handleError(message: string, error) {
// if(error == null) {
// this.formComponent.reset();
@ -464,43 +429,43 @@ export class PagesComponent implements OnInit {
this.errorMessage = message;// + ' (Server responded: ' + error + ')';
console.log('Server responded: ' + error);
//}
this.showLoading = false;
}
handleUpdateError(message: string, error) {
if (error == null) {
// this.formComponent.reset();
this.myForm = this._fb.group({
route: ['', Validators.required],
name: ['', Validators.required],
isEnabled: true,
portalType: ['', Validators.required],
top: true,
bottom: true,
left: true,
right: true,
type: ['', Validators.required],
entities: this._fb.array([]),
_id: '',
this.pageForm = this._fb.group({
route: this._fb.control('', Validators.required),
name: this._fb.control('', Validators.required),
isEnabled: this._fb.control(true),
portalType: this._fb.control('', Validators.required),
top: this._fb.control(true),
bottom: this._fb.control(true),
left: this._fb.control(true),
right: this._fb.control(true),
type: this._fb.control(this.typeOptions[0].value, Validators.required),
entities: this.entitiesCtrl,
_id: this._fb.control(''),
});
} else {
this.updateErrorMessage = message;// + ' (Server responded: ' + error + ')';
console.log('Server responded: ' + error);
}
this.showLoading = false;
}
// public filterByPortal(event: any) {
// this.portal = event.target.value;
// this.applyPortalFilter(this.portal);
// }
public applyPortalFilter(portal: string) {
this.getPages(portal);
}
public togglePages(status: boolean, ids: string[]) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
@ -511,7 +476,7 @@ export class PagesComponent implements OnInit {
});
} else {
this.updateErrorMessage = '';
this.subscriptions.push(this._helpContentService.togglePages(this.portal, ids, status, this.properties.adminToolsAPIURL).subscribe(
() => {
for (let id of ids) {
@ -524,33 +489,8 @@ export class PagesComponent implements OnInit {
));
}
}
public capitalizeFirstLetter(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
remove(entity): void {
let index = this.selectedEntities.indexOf(entity);
console.log(entity);
console.log(this.selectedEntities);
console.log(index)
if (index >= 0) {
this.selectedEntities.splice(index, 1);
this.entitiesCtrl.value.splice(index, 1);
this.entitiesCtrl.markAsDirty();
}
}
selected(event: MatAutocompleteSelectedEvent): void {
let newEntity = event.option.value;
if (this.selectedEntities.indexOf(newEntity) == -1) {
this.selectedEntities.push(event.option.value);
this.entitiesCtrl.push(this._fb.control(newEntity));
this.entitiesCtrl.markAsDirty();
}
this.pageInput.nativeElement.value = '';
this.entitiesSearchCtrl.setValue('');
}
}

View File

@ -101,19 +101,19 @@
</div>
</div>
<modal-alert #portalModal (alertOutput)="portalSaveConfirmed($event)"
[okDisabled]="portalFG && (portalFG.invalid || !portalFG.dirty)">
<modal-alert #editModal (alertOutput)="portalSaveConfirmed($event)"
[okDisabled]="portalForm && (portalForm.invalid || !portalForm.dirty)">
<div *ngIf="modalErrorMessage" class="uk-alert-danger" uk-alert aria-hidden="true">{{ modalErrorMessage }}</div>
<form [formGroup]="portalFG" class="uk-grid uk-child-width-1-1" uk-grid>
<div dashboard-input [formInput]="portalFG.get('name')" type="text" label="Portal Name" placeholder="Write a name">
<form *ngIf="portalForm" [formGroup]="portalForm" class="uk-grid uk-child-width-1-1" uk-grid>
<div dashboard-input [formInput]="portalForm.get('name')" type="text" label="Portal Name" placeholder="Write a name">
</div>
<div dashboard-input type="select" label="Portal Type" placeholder="Choose a type" [formInput]="portalFG.get('type')" [options]="portalUtils.portalTypes"></div>
<div dashboard-input [formInput]="portalFG.get('pid')"
type="text"
<div dashboard-input type="select" label="Portal Type" placeholder="Choose a type" [formInput]="portalForm.get('type')" [options]="portalUtils.portalTypes"></div>
<div dashboard-input [formInput]="portalForm.get('pid')"
type="text" placeholder="Write pid of portal"
label="Portal persistent id for portal">
</div>
<div dashboard-input [formInput]="portalFG.get('piwik')"
type="text"
<div dashboard-input [formInput]="portalForm.get('piwik')"
type="text" placeholder="Write piwik id of portal"
label="Piwik id">
</div>
<input type="hidden" formControlName="_id">

View File

@ -1,7 +1,7 @@
import {Component, ViewChild, OnInit, ElementRef} from '@angular/core';
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {HelpContentService} from '../../services/help-content.service';
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {EnvProperties} from '../../utils/properties/env-properties';
import {Session} from '../../login/utils/helper.class';
@ -11,7 +11,6 @@ import {Subscriber} from "rxjs";
import {CheckPortal, Portal} from "../../utils/entities/adminTool/portal";
import {PortalUtils} from "./portalHelper";
import {properties} from "../../../../environments/environment";
import {CheckPage, Page} from "../../utils/entities/adminTool/page";
import {AlertModal} from "../../utils/modal/alert";
@Component({
@ -21,14 +20,14 @@ import {AlertModal} from "../../utils/modal/alert";
export class PortalsComponent implements OnInit {
@ViewChild('portalModal') portalModal: AlertModal;
@ViewChild('editModal') editModal: AlertModal;
@ViewChild('deleteModal') deleteModal: AlertModal;
private selectedPortals: string[] = [];
public checkboxes: CheckPortal[] = [];
public portals: Portal[] = [];
public portalFG: FormGroup;
public portalForm: FormGroup;
public filterForm: FormGroup;
private subscriptions: any[] = [];
@ -42,15 +41,9 @@ export class PortalsComponent implements OnInit {
public updateErrorMessage = '';
public modalErrorMessage = '';
public portalUtils: PortalUtils = new PortalUtils();
private index: number;
ngOnInit() {
this.portalFG = this._fb.group({
name: this._fb.control('', Validators.required),
_id: this._fb.control(''),
pid: this._fb.control('', Validators.required),
piwik: this._fb.control(''),
type: this._fb.control('', Validators.required),
});
this.filterForm = this._fb.group({
keyword: [''],
type: ['all', Validators.required]
@ -122,9 +115,11 @@ export class PortalsComponent implements OnInit {
private deletePortalsFromArray(ids: string[]): void {
for (let id of ids) {
let i = this.checkboxes.findIndex(_ => _.portal._id === id);
this.checkboxes.splice(i, 1);
let i = this.portals.findIndex(_ => _._id == id);
this.portals.splice(i, 1);
}
this.applyTypeFilter();
this.applyFilter();
}
public confirmDeletePortal(id: string) {
@ -140,12 +135,21 @@ export class PortalsComponent implements OnInit {
}
private confirmModalOpen() {
this.deleteModal.cancelButton = true;
this.deleteModal.okButton = true;
this.deleteModal.alertTitle = 'Delete Confirmation';
this.deleteModal.message = 'Are you sure you want to delete the selected portal(-ies)?';
this.deleteModal.okButtonText = 'Yes';
this.deleteModal.open();
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
queryParams: {
"errorCode": LoginErrorCodes.NOT_VALID,
"redirectUrl": this._router.url
}
});
} else {
this.deleteModal.cancelButton = true;
this.deleteModal.okButton = true;
this.deleteModal.alertTitle = 'Delete Confirmation';
this.deleteModal.message = 'Are you sure you want to delete the selected portal(-ies)?';
this.deleteModal.okButtonText = 'Yes';
this.deleteModal.open();
}
}
public confirmedDeletePortals(data: any) {
@ -169,45 +173,63 @@ export class PortalsComponent implements OnInit {
public editPortal(i: number) {
const portal: Portal = this.checkboxes[i].portal;
this.portalFG = this._fb.group({
name: this._fb.control(portal.name, Validators.required),
this.index = this.portals.findIndex(value => value._id === portal._id);
this.portalForm = this._fb.group({
_id: this._fb.control(portal._id),
name: this._fb.control(portal.name, Validators.required),
pid: this._fb.control(portal.pid, Validators.required),
piwik: this._fb.control(portal.piwik),
type: this._fb.control(portal.type, Validators.required),
});
this.portalFG.controls['type'].disable();
this.portalForm.controls['type'].disable();
this.modalErrorMessage = '';
this.portalModalOpen('Update Portal', 'Update');
this.portalModalOpen('Edit Portal', 'Save');
}
public newPortal() {
this.portalFG.controls['type'].enable();
this.portalFG = this._fb.group({
name: this._fb.control('', Validators.required),
this.portalForm.controls['type'].enable();
this.portalForm = this._fb.group({
_id: this._fb.control(''),
name: this._fb.control('', Validators.required),
pid: this._fb.control('', Validators.required),
piwik: this._fb.control(''),
type: this._fb.control('', Validators.required),
});
this.modalErrorMessage = '';
this.portalModalOpen('Create Portal', 'Save');
this.portalModalOpen('Create Portal', 'Create');
}
private portalModalOpen(title: string, yesBtn: string) {
this.portalModal.okButtonLeft = false;
this.portalModal.cancelButton = true;
this.portalModal.okButton = true;
this.portalModal.alertTitle = title;
this.portalModal.okButtonText = yesBtn;
this.portalModal.open();
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
queryParams: {
"errorCode": LoginErrorCodes.NOT_VALID,
"redirectUrl": this._router.url
}
});
} else {
this.editModal.okButtonLeft = false;
this.editModal.cancelButton = true;
this.editModal.okButton = true;
this.editModal.alertTitle = title;
this.editModal.okButtonText = yesBtn;
this.editModal.open();
}
}
public portalSaveConfirmed(data: any) {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
queryParams: {
"errorCode": LoginErrorCodes.NOT_VALID,
"redirectUrl": this._router.url
}
});
} else {
this.modalErrorMessage = '';
if (this.portalFG.getRawValue()['_id'].length > 0) {
this.portalFG.controls['type'].enable();
this.subscriptions.push(this._helpContentService.updateCommunity(<Portal>this.portalFG.value,
if (this.portalForm.value._id) {
this.portalForm.controls['type'].enable();
this.subscriptions.push(this._helpContentService.updateCommunity(<Portal>this.portalForm.value,
this.properties.adminToolsAPIURL).subscribe(
portal => {
this.portalUpdatedSuccessfully(portal);
@ -215,7 +237,7 @@ export class PortalsComponent implements OnInit {
error => this.handleUpdateError('System error updating portal', error)
));
} else {
this.subscriptions.push(this._helpContentService.saveCommunity(<Portal>this.portalFG.value,
this.subscriptions.push(this._helpContentService.saveCommunity(<Portal>this.portalForm.value,
this.properties.adminToolsAPIURL).subscribe(
portal => {
this.portalSavedSuccessfully(portal);
@ -223,6 +245,7 @@ export class PortalsComponent implements OnInit {
error => this.handleUpdateError('System error creating portal', error)
));
}
}
}
public portalUpdateConfirmed(data: any) {
@ -231,8 +254,8 @@ export class PortalsComponent implements OnInit {
queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url}
});
} else {
this.portalFG.controls['type'].enable();
this.subscriptions.push(this._helpContentService.updateCommunity(<Portal>this.portalFG.value,
this.portalForm.controls['type'].enable();
this.subscriptions.push(this._helpContentService.updateCommunity(<Portal>this.portalForm.value,
this.properties.adminToolsAPIURL).subscribe(
portal => {
this.portalUpdatedSuccessfully(portal);
@ -243,12 +266,16 @@ export class PortalsComponent implements OnInit {
}
public portalSavedSuccessfully(portal: Portal) {
this.checkboxes.push(<CheckPortal>{portal: portal, checked: false});
this.portals.push(portal)
this.applyTypeFilter();
this.applyFilter();
this.applyCheck(false);
}
public portalUpdatedSuccessfully(portal: Portal) {
this.checkboxes.find(checkItem => checkItem.portal._id === portal._id).portal = portal;
this.portals[this.index] = portal;
this.applyTypeFilter();
this.applyFilter();
this.applyCheck(false);
}
@ -283,7 +310,7 @@ export class PortalsComponent implements OnInit {
handleUpdateError(message: string, error) {
if (error == null) {
this.portalFG = this._fb.group({
this.portalForm = this._fb.group({
name: '',
_id: '',
pid: '',
@ -294,14 +321,12 @@ export class PortalsComponent implements OnInit {
this.updateErrorMessage = message;
console.log('Server responded: ' + error);
}
this.showLoading = false;
}
handleError(message: string, error) {
this.errorMessage = message;
console.log('Server responded: ' + error);
this.showLoading = false;
}
}

View File

@ -1,8 +1,10 @@
import {Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild} from "@angular/core";
import {AbstractControl} from "@angular/forms";
import {AbstractControl, FormArray, FormControl} from "@angular/forms";
import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {Subscription} from "rxjs";
import {Observable, of, Subscription} from "rxjs";
import {MatSelect} from "@angular/material/select";
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
import {map, startWith} from "rxjs/operators";
export interface Option {
@ -15,11 +17,13 @@ export interface Option {
@Component({
selector: '[dashboard-input]',
template: `
<div *ngIf="label && type != 'checkbox'" class="uk-text-bold uk-form-label uk-margin-small-bottom">{{label + (required ? ' *' : '')}}</div>
<div *ngIf="label && type != 'checkbox'"
class="uk-text-bold uk-form-label uk-margin-small-bottom">{{label + (required ? ' *' : '')}}</div>
<div *ngIf="hint" class="uk-margin-bottom uk-text-small uk-form-hint">{{hint}}</div>
<div class="uk-grid uk-flex uk-flex-middle" [class.uk-grid-small]="gridSmall" uk-grid>
<ng-content></ng-content>
<div [class.uk-hidden]="hideControl" class="uk-width-expand uk-position-relative" [class.uk-flex-first]="!extraLeft">
<div [class.uk-hidden]="hideControl" class="uk-width-expand uk-position-relative"
[class.uk-flex-first]="!extraLeft">
<ng-template [ngIf]="icon && formControl.enabled">
<span class="uk-text-muted" [ngClass]="iconLeft?('left'):'right'">
<icon [name]="icon"></icon>
@ -31,19 +35,27 @@ export interface Option {
</span>
</ng-template>
<ng-template [ngIf]="type === 'text'">
<input class="uk-input input-box uk-text-small" [attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':''" [placeholder]="placeholder" [formControl]="formControl"
<input class="uk-input input-box uk-text-small"
[attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':''"
[placeholder]="placeholder" [formControl]="formControl"
[class.uk-form-danger]="formControl.invalid && formControl.touched">
</ng-template>
<ng-template [ngIf]="type === 'textarea'">
<textarea class="uk-textarea input-box uk-text-small" [attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':''" [rows]="rows" [placeholder]="placeholder"
<textarea class="uk-textarea input-box uk-text-small"
[attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':''"
[rows]="rows" [placeholder]="placeholder"
[formControl]="formControl" [class.uk-form-danger]="formControl.invalid && formControl.touched">
</textarea>
</ng-template>
<ng-template [ngIf]="type === 'select'">
<div class="input-box" [attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':null" [class.clickable]="formControl.enabled" [class.uk-form-danger]="formControl.invalid && formControl.touched" (click)="openSelect()">
<div class="input-box"
[attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':null"
[class.clickable]="formControl.enabled"
[class.uk-form-danger]="formControl.invalid && formControl.touched" (click)="openSelect()">
<mat-form-field class="uk-width-1-1">
<mat-select #select *ngIf="type === 'select'" [required]="required" [value]="null"
(openedChange)="stopPropagation()" [formControl]="formControl" [disableOptionCentering]="true">
<mat-select #select [required]="required" [value]="null"
(openedChange)="stopPropagation()" [formControl]="formControl"
[disableOptionCentering]="true">
<mat-option *ngIf="placeholder" class="uk-hidden" [value]="''">{{placeholder}}</mat-option>
<mat-option *ngFor="let option of options" [value]="option.value">
{{option.label}}
@ -52,7 +64,36 @@ export interface Option {
</mat-form-field>
</div>
</ng-template>
<span *ngIf="formControl.invalid && formControl.errors.error" class="uk-text-danger input-message">{{formControl.errors.error}}</span>
<ng-template [ngIf]="type === 'chips'">
<div class="input-box"
[attr.uk-tooltip]="formControl.disabled?'title: This field is not editable; pos: bottom-left':null"
[class.clickable]="formControl.enabled"
[class.uk-form-danger]="formControl.invalid && formControl.touched" (click)="openSelect()">
<mat-form-field class="uk-width-1-1">
<mat-chip-list #chipList aria-label="Page selection">
<mat-chip *ngFor="let chip of formAsArray.controls; let i=index"
(removed)="removed(i)"
[removable]="removable">
{{chip.value[chipLabel]}}
<span (click)="removed(i)"
class="mat-chip-remove mat-chip-trailing-icon" uk-icon="close"></span>
</mat-chip>
<div class="uk-width-expand uk-position-relative uk-text-small">
<input #searchInput class="uk-width-1-1" [formControl]="searchControl" [matAutocomplete]="auto" [matChipInputFor]="chipList">
<div *ngIf="placeholder && !searchControl.value" class="placeholder uk-width-1-1"
(click)="searchInput.focus()">{{placeholder}}</div>
</div>
</mat-chip-list>
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option.value">
{{option.label}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
</ng-template>
<span *ngIf="formControl.invalid && formControl.errors.error"
class="uk-text-danger input-message">{{formControl.errors.error}}</span>
<span *ngIf="warning" class="uk-text-warning input-message">{{warning}}</span>
<span *ngIf="note" class="input-message">{{note}}</span>
</div>
@ -63,7 +104,7 @@ export interface Option {
})
export class InputComponent implements OnInit, OnDestroy, OnChanges {
@Input('formInput') formControl: AbstractControl;
@Input('type') type: 'text' | 'textarea' | 'select' | 'checkbox' = 'text';
@Input('type') type: 'text' | 'textarea' | 'select' | 'checkbox' | 'chips' = 'text';
@Input('label') label: string;
@Input('rows') rows: number = 3;
@Input('options') options: Option[];
@ -77,9 +118,14 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
@Input() iconLeft: boolean = false;
@Input() warning: string = null;
@Input() note: string = null;
@Input() removable: boolean = true;
@Input() chipLabel: string = null;
public filteredOptions: Observable<Option[]>;
public searchControl: FormControl;
public required: boolean = false;
private initValue: any;
private subscriptions: any[] = [];
@ViewChild('searchInput') searchInput;
constructor() {
}
@ -94,9 +140,19 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
}
}
get formAsArray(): FormArray {
return (<FormArray> this.formControl);
}
reset() {
this.unsubscribe();
this.initValue = HelperFunctions.copy(this.formControl.value);
if(this.options && this.type === 'chips') {
this.filteredOptions = of(this.options);
this.searchControl = new FormControl('');
this.filteredOptions = this.searchControl.valueChanges.pipe(startWith(''),
map(option => this.filter(option)));
}
if (this.formControl && this.formControl.validator) {
let validator = this.formControl.validator({} as AbstractControl);
this.required = (validator && validator.required);
@ -133,4 +189,25 @@ export class InputComponent implements OnInit, OnDestroy, OnChanges {
stopPropagation() {
event.stopPropagation();
}
removed(index: number) {
this.formAsArray.removeAt(index);
this.formAsArray.markAsDirty();
}
selected(event: MatAutocompleteSelectedEvent): void {
this.formAsArray.push(new FormControl(event.option.value));
this.formAsArray.markAsDirty();
this.searchControl.setValue('');
this.searchInput.nativeElement.value = '';
}
private filter(value: string): Option[] {
let options = this.options.filter(option => !this.formAsArray.value.find(value => option.label === value[this.chipLabel]));
if (!value || value.length == 0) {
return options;
}
const filterValue = value.toString().toLowerCase();
return options.filter(option => option.label.toLowerCase().indexOf(filterValue) != -1);
}
}

View File

@ -8,6 +8,9 @@ import {MatCheckboxModule} from '@angular/material/checkbox';
import {IconsModule} from "../../utils/icons/icons.module";
import {IconsService} from "../../utils/icons/icons.service";
import {lock} from "../../utils/icons/icons";
import {MatChipsModule} from "@angular/material/chips";
import {MatAutocompleteModule} from "@angular/material/autocomplete";
import {MatIconModule} from "@angular/material/icon";
@NgModule({
imports: [
@ -16,7 +19,10 @@ import {lock} from "../../utils/icons/icons";
MatInputModule,
MatSelectModule,
MatCheckboxModule,
IconsModule
IconsModule,
MatChipsModule,
MatAutocompleteModule,
MatIconModule
],
exports: [
InputComponent