Notify form: Open dropdown on empty. Delele unsused mailPrefsComponent. Finish UI of subscribers and invite subscriber. Fix an input bug in case of adding chip with enter key

This commit is contained in:
Konstantinos Triantafyllou 2022-06-28 21:13:40 +03:00
parent a85ec2bfbd
commit 9b5607fbd0
12 changed files with 117 additions and 502 deletions

View File

@ -1,55 +0,0 @@
<div *ngIf="!hidden" class="">
<div *ngIf="showSaveResetButtons" class="uk-article-title custom-article-title">
User Email Preferences for Claims Notifications
</div>
<div *ngIf="userValidMessage.length > 0" class = "uk-alert uk-alert-danger uk-animation-fade" role="alert">
{{userValidMessage}}
</div>
<div *ngIf="savedMessage.length > 0" class="uk-alert uk-alert-success uk-animation-fade" role="alert">
{{savedMessage}}
</div>
<errorMessages [status]="[status]" [type]="'notification preferences'"></errorMessages>
<div *ngFor="let notification of notifications; let i=index" >
<!-- <div class="uk-accordion-title">Email preferences for {{preferencesFor}}: <strong>{{notification.openaireName}}</strong></div>-->
<!-- <div class="uk-accordion-content">-->
<form class="uk-form-horizontal"><!-- [formGroup]="myForm"-->
<!--[ngClass]="{'has-error':!myForm.controls.notify.valid && myForm.controls.notify.dirty}"-->
<div class="uk-margin uk-grid">
<div class=" inherit-color uk-width-medium"
title="Get e-mail notification when there are new user links related your community">Notify
for new user links:</div>
<mat-slide-toggle [checked]="notification.notify"
(change)="($event.source.checked = notification.notify);changeNotify(notification, !notification.notify, i)"></mat-slide-toggle>
</div>
<div *ngIf="notification.notify" [class]="notification.notify ? 'uk-margin' :
'uk-margin cursor-not-allowed'">
<div class="uk-form-label inherit-color">Frequency:</div>
<div class="uk-form-controls">
<select [class]="notification.notify ? 'uk-select' : 'uk-select uk-disabled'" id="form-horizontal-select"
[(ngModel)]="notification.frequency" (ngModelChange)="changeFrequency(i)" name="select_frequency">
<option [ngValue]="24" >Daily</option>
<option [ngValue]="48" >Every two days</option>
<option [ngValue]="168">Weekly</option>
</select>
</div>
</div>
<div *ngIf="showSaveResetButtons" class="uk-float-right">
<button type="submit" class="uk-button uk-button-primary" (click)="saveNotification(i)">Save Changes</button>
<button type="submit" class="uk-button" (click)="restoreNotification(i)">Reset</button>
</div>
</form>
</div>
<!-- </div>-->
<!-- </ul>-->
</div>

View File

@ -1,259 +0,0 @@
import {Component, Input} from '@angular/core';
import {Location} from '@angular/common';
import {ActivatedRoute, Router} from '@angular/router';
import {Session} from '../../login/utils/helper.class';
import {EnvProperties} from '../../utils/properties/env-properties';
import {MailPrefsService} from './mailPrefs.service';
import {ConnectHelper} from '../connectHelper';
import {ErrorCodes} from '../../utils/properties/errorCodes';
import {ErrorMessagesComponent} from '../../utils/errorMessages.component';
import {LoginErrorCodes} from '../../login/utils/guardHelper.class';
import {properties} from "../../../../environments/environment";
import {Subscriber} from "rxjs";
declare var UIkit: any;
@Component({
selector: 'mailPrefs',
templateUrl: 'mailPrefs.component.html',
providers:[MailPrefsService]
})
export class MailPrefsComponent {
properties:EnvProperties;
subscriptions = [];
@Input() communityId: string;
public preferencesFor: string = "community";
public status: number;
public notifications = [];
public initialNotifications = [];
public prefsChanged = {};
public hidden: boolean = true;
//public showForbiddenMessage:boolean = false;
public userValidMessage:string = "";
public savedMessage: string = "";
private errorCodes: ErrorCodes;
private errorMessages: ErrorMessagesComponent;
@Input() showSaveResetButtons: boolean = true;
constructor (private _mailPrefsService: MailPrefsService, private route: ActivatedRoute, private _router:Router, private location: Location) {
this.errorCodes = new ErrorCodes();
this.errorMessages = new ErrorMessagesComponent();
this.status = this.errorCodes.LOADING;
}
ngOnInit() {
this.properties = properties;
this.subscriptions.push(this.route.params.subscribe(params => {
this.hidden = true;
console.debug(this.communityId);
if(!this.communityId){
this.communityId = ConnectHelper.getCommunityFromDomain(this.properties.domain);
}
if(!this.communityId) {
this.communityId = params['community'];
}
console.debug(this.communityId, params)
this.getEmailPreferences();
}));
}
getEmailPreferences() {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
this.status = this.errorCodes.LOADING;
this.savedMessage = "";
if(this.communityId && this.communityId != "openaire") {
this.preferencesFor = "community";
this.subscriptions.push(this._mailPrefsService.getUserEmailPreferencesForCommunity(this.communityId, this.properties.claimsAPIURL).subscribe(
data => {
if(data.code == "204") {
this.status = this.errorCodes.NONE;
this.initialNotifications = [{notify: true, frequency:24, openaireId: this.communityId}];
} else {
this.initialNotifications = data.data;
}
this.notifications = JSON.parse(JSON.stringify( this.initialNotifications ));
this.status = this.errorCodes.DONE;
this.hidden = false;
},
err => {
this.hidden = false;
this.handleErrors(err);
this.handleError("Error getting user email preferences for community with id: "+this.communityId, err);
}
));
} else {
this.preferencesFor = "project";
this.subscriptions.push(this._mailPrefsService.getUserEmailPreferencesForOpenaire(this.properties.claimsAPIURL).subscribe(
data => {
if(data.code == "204") {
this.status = this.errorCodes.NONE;
} else {
this.initialNotifications = data.data;
this.notifications = JSON.parse(JSON.stringify( this.initialNotifications ));
//this.notifications = this.initialNotifications.map(x => Object.assign({}, x));
//this.notifications = this.initialNotifications;
this.status = this.errorCodes.DONE;
}
},
err => {
//console.info(err);
this.handleErrors(err);
this.handleError("Error getting user email preferences for openaire", err);
}
));
}
}
}
changeNotify(notification: any, checked: boolean, index: number) {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
this.savedMessage = "";
this.status = this.errorCodes.DONE;
notification.notify = checked;
this.prefsChanged[index] = true;
}
}
changeFrequency(index: number) {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
this.savedMessage = "";
this.status = this.errorCodes.DONE;
if(this.initialNotifications[index].frequency != this.notifications[index].frequency) {
this.prefsChanged[index] = true;
}
}
}
saveNotification(index: number) {
if(this.notifications.length > 0 && this.initialNotifications.length > 0) {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
if(JSON.stringify(this.notifications[index]) != JSON.stringify(this.initialNotifications[index])) {
this.status = this.errorCodes.LOADING;
this.savedMessage = "";
this.subscriptions.push(this._mailPrefsService.saveUserEmailPreferences(this.notifications[index], this.properties.claimsAPIURL).subscribe(
data => {
this.initialNotifications[index] = JSON.parse(JSON.stringify( this.notifications[index] ));
this.status = this.errorCodes.DONE;
/*UIkit.notification({
message : '<strong>Your email preferences for '+this.notifications[index].openaireName+' have been successfully changed<strong>',
status : 'success',
timeout : 3000,
pos : 'top-center'
});*/
this.savedMessage = "Notification settings for claims saved!";
},
err => {
//console.log(err);
this.handleError("Error saving user email preferences: "+JSON.stringify(this.notifications[index]), err);
this.status = this.errorCodes.NOT_SAVED;
}
));
}
else {
/*UIkit.notification({
message : '<strong>No changes selected for '+this.notifications[index].openaireName+' email preferences<strong>',
status : 'primary',
timeout : 3000,
pos : 'top-center'
});*/
this.savedMessage = "Notification settings for claims saved!";
}
}
}
}
restoreNotification(index: number) {
if(!Session.isLoggedIn()){
//this.userValidMessage = "User session has expired. Please login again.";
if(this.showSaveResetButtons) {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
}
} else {
if(this.notifications.length > 0 && this.initialNotifications.length > 0) {
this.status = this.errorCodes.LOADING;
this.savedMessage = "";
this.notifications[index] = JSON.parse(JSON.stringify( this.initialNotifications[index] ));
this.status = this.errorCodes.DONE;
this.prefsChanged[index] = false;
}
}
}
/*
prefsChanged(index: number) : boolean {
if(this.notifications.length > 0 && this.initialNotifications.length > 0) {
if(JSON.stringify(this.notifications[index]) != JSON.stringify(this.initialNotifications[index])) {
return true;
}
}
return false;
}
*/
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
}
handleErrors(err){
//this.showErrorMessage = true;
//try{
var code = "";
if(!err.status) {
var error = err.json();
code = error.code;
} else {
code = err.status;
}
this.status = this.errorMessages.getErrorCode(code);
}
private handleError(message: string, error) {
console.error("User mail notification preferences Page (for claims): "+message, error);
}
//}catch (e) {
//console.log("Couldn't parse answer as json")
//this.showErrorMessage = true;
//}
}

View File

@ -8,46 +8,15 @@ export class MailPrefsService {
constructor(private http: HttpClient ) {}
getUserEmailPreferencesForCommunity (communityId:string, apiUrl:string):any {
let url = apiUrl +"users/notification"+"?communityId="+communityId;
return this.http.get(url, CustomOptions.getAuthOptions())
//.map(request => <any> request.json())
//.do(request => console.info("Get user email preferences for communityId= "+communityId ));
//.catch(this.handleError);
return this.http.get(apiUrl +"users/notification"+"?communityId="+communityId, CustomOptions.getAuthOptions())
}
getUserEmailPreferencesForOpenaire (apiUrl:string):any {
let url = apiUrl +"users/notification";
//var error: HttpErrorResponse = new HttpErrorResponse({"error": {"code": 204}, "status" : 204}); // doesn't work
//var response: Response = new Response({"body" : {"code":200, "data": []}, "status": 200, "headers": null, "url": "", "merge": null});
return this.http.get(url, CustomOptions.getAuthOptions())
//.timeoutWith(100, Observable.throw(response)) // goes to error
//.timeoutWith(100, Observable.of(response)) // goes to
//.do(request => console.info(request))
//.map(request => <any> request.json())
//.do(request => console.info("Get user email preferences for OpenAIRE" ));
//.catch(this.handleError);
return this.http.get(apiUrl +"users/notification", CustomOptions.getAuthOptions());
}
saveUserEmailPreferences (notification: any, apiUrl: string) {
let url = apiUrl +"users/notification/save";
let body = JSON.stringify( notification );
//console.warn('Json body: : '+body);
//let headers = new Headers({ 'Content-Type': 'application/json' });
//let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody())
//.map(res => res.json())
//.do(request => console.info("Insert Response:"+request.status) );
//.catch(this.handleError);
}
private handleError (error: HttpErrorResponse) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.log(error);
return throwError(error || 'Server error');
let body = JSON.stringify(notification);
return this.http.post(apiUrl +"users/notification/save", body, CustomOptions.getAuthOptionsWithBody());
}
}

View File

@ -1,23 +0,0 @@
import { NgModule} from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MailPrefsComponent } from './mailPrefs.component';
import { MailPrefsService } from './mailPrefs.service';
import {ErrorMessagesModule} from '../../utils/errorMessages.module';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@NgModule({
imports: [
CommonModule, RouterModule, FormsModule, ReactiveFormsModule, ErrorMessagesModule, MatSlideToggleModule
],
declarations: [
MailPrefsComponent
],
providers:[MailPrefsService],
exports: [
MailPrefsComponent
]
})
export class MailPrefsModule { }

View File

@ -3,10 +3,7 @@
<ng-content></ng-content>
</div>
<div inner>
<div *ngIf="loadActive || loadPending" class="uk-position-center">
<loading></loading>
</div>
<div class="uk-grid uk-margin-medium-bottom uk-margin-top" uk-grid>
<div class="uk-grid uk-margin-top" uk-grid>
<div class="uk-flex uk-flex-left@m uk-flex-center uk-width-expand">
<ul class="uk-subnav uk-subnav-pill">
<li [class.uk-active]="showCurrent" (click)="showCurrent = true">
@ -25,7 +22,8 @@
[searchControl]="filterForm.get('pending')" [expandable]="true" [placeholder]="'Search invitations'" searchInputClass="outer">
</div>
<div>
<button *ngIf="exists" class="uk-button uk-button-default uk-flex uk-flex-middle" [attr.uk-tooltip]="inviteDisableMessage"
<button *ngIf="exists" class="uk-button uk-button-default uk-flex uk-flex-middle"
[attr.uk-tooltip]="inviteDisableMessage" [class.uk-disabled]="loadPending || !!inviteDisableMessage"
[disabled]="loadPending || !!inviteDisableMessage" (click)="openInviteModal()">
<icon name="person_add" [flex]="true" type="filled"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">Invite {{role}}</span>
@ -38,40 +36,45 @@
</div>
</div>
</div>
<div *ngIf="!loadActive && !loadPending" class="uk-section uk-section-small">
<div *ngIf="(showCurrent && showActive.length == 0) || (!showCurrent && showPending.length == 0)"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div *ngIf="showCurrent">No {{role}}s found</div>
<div *ngIf="!showCurrent">No pending {{role}} invitations found</div>
</div>
<div *ngIf="(showCurrent && showActive.length > 0) || (!showCurrent && showPending.length > 0)">
<no-load-paging *ngIf="showCurrent" [type]="(showActive.length > 1)?(role + 's'):role"
(pageChange)="updateActivePage($event)"
[page]="activePage" [pageSize]="pageSize"
[totalResults]="showActive.length">
</no-load-paging>
<no-load-paging *ngIf="!showCurrent" [type]="role + ' ' + (showPending.length > 1?'invitations':'invitation')"
(pageChange)="updatePendingPage($event)"
[page]="pendingPage" [pageSize]="pageSize"
[totalResults]="showPending.length">
</no-load-paging>
<div class="uk-grid uk-grid-large uk-child-width-1-1@s uk-child-width-1-2@m uk-margin-top" uk-grid>
<div *ngFor="let item of (showCurrent)?(currentActivePage):(currentPendingPage)">
<div class="uk-card uk-card-default">
<div class="uk-card-body">
<span class="uk-text-bold uk-text-large">{{(showCurrent) ? item.email : item}}</span>
</div>
<div *ngIf="isCurator || !showCurrent" class="uk-card-footer uk-flex uk-flex-right">
<button (click)="openDeleteModal(item)" class="uk-button uk-button-link uk-flex uk-flex-middle" [disabled]="role === 'member' && item.isManager"
[attr.uk-tooltip]="(role === 'member' && item.isManager)?'This user is a manager and cannot be removed.':null">
<icon name="delete" [flex]="true" type="filled"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">{{showCurrent ? 'Delete' : 'Cancel invitation'}}</span>
</button>
<div class="uk-section uk-section-small">
<div *ngIf="loadActive || loadPending" class="uk-position-center">
<loading></loading>
</div>
<div *ngIf="!loadActive && !loadPending">
<div *ngIf="(showCurrent && showActive.length == 0) || (!showCurrent && showPending.length == 0)"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div *ngIf="showCurrent">No {{role}}s found</div>
<div *ngIf="!showCurrent">No pending {{role}} invitations found</div>
</div>
<div *ngIf="(showCurrent && showActive.length > 0) || (!showCurrent && showPending.length > 0)">
<no-load-paging *ngIf="showCurrent" [type]="(showActive.length > 1)?(role + 's'):role"
(pageChange)="updateActivePage($event)"
[page]="activePage" [pageSize]="pageSize"
[totalResults]="showActive.length">
</no-load-paging>
<no-load-paging *ngIf="!showCurrent" [type]="role + ' ' + (showPending.length > 1?'invitations':'invitation')"
(pageChange)="updatePendingPage($event)"
[page]="pendingPage" [pageSize]="pageSize"
[totalResults]="showPending.length">
</no-load-paging>
<div class="uk-grid uk-grid-large uk-child-width-1-1@s uk-child-width-1-2@m uk-margin-top" uk-grid>
<div *ngFor="let item of (showCurrent)?(currentActivePage):(currentPendingPage)">
<div class="uk-card uk-card-default">
<div class="uk-card-body">
<span class="uk-text-bold uk-text-large">{{(showCurrent) ? item.email : item}}</span>
</div>
<div *ngIf="isCurator || !showCurrent" class="uk-card-footer uk-flex uk-flex-right">
<button (click)="openDeleteModal(item)" class="uk-button uk-button-link uk-flex uk-flex-middle" [disabled]="role === 'member' && item.isManager"
[attr.uk-tooltip]="(role === 'member' && item.isManager)?'This user is a manager and cannot be removed.':null">
<icon name="delete" [flex]="true" type="filled"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">{{showCurrent ? 'Delete' : 'Cancel invitation'}}</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,78 +1,64 @@
<div page-content>
<div page-content (stickyEmitter)="stickyEmitter.emit($event)">
<div header>
<ng-content></ng-content>
<div [class.uk-invisible]="loading"
class="uk-flex uk-flex-right@m uk-flex-center uk-flex-wrap uk-flex-middle uk-grid" uk-grid>
<div search-input [control]="filterForm.get('keyword')" [showSearch]="false" placeholder="Search subscribers"
[bordered]="true" colorClass="uk-text-secondary">
</div>
<div>
<a *ngIf="exists" class="uk-text-uppercase uk-flex uk-flex-middle" [attr.uk-tooltip]="(inviteDisableMessage)">
<button class="uk-icon-button large uk-button-secondary" (click)="openInviteModal()"
[disabled]="!subscriberInvite || subscriberInvite.loading || !!inviteDisableMessage">
<icon name="person_add"></icon>
</button>
<button class="uk-button uk-button-link uk-margin-small-left" (click)="openInviteModal()"
[disabled]="!subscriberInvite || subscriberInvite.loading || !!inviteDisableMessage"
[class.uk-text-secondary]="subscriberInvite && !subscriberInvite.loading && !inviteDisableMessage">
Invite Subscribers
</button>
</a>
<a *ngIf="!exists && isPortalAdmin" class="uk-text-uppercase uk-flex uk-flex-middle"
(click)="openCreateRoleModal()">
<button class="uk-icon-button large uk-button-secondary">
<icon name="person_add"></icon>
</button>
<button class="uk-button uk-button-link uk-margin-small-left uk-text-secondary">Create Group</button>
</a>
</div>
</div>
</div>
<div inner>
<div [class.uk-invisible]="loading"
class="uk-flex uk-flex-right@m uk-flex-center uk-margin-top uk-flex-middle uk-grid" uk-grid>
<div search-input [searchControl]="filterForm.get('keyword')" placeholder="Search members"
[expandable]="true" searchInputClass="outer" class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1">
</div>
<div>
<button *ngIf="exists" class="uk-button uk-button-default uk-flex uk-flex-middle"
[attr.uk-tooltip]="inviteDisableMessage"
[disabled]="!subscriberInvite || subscriberInvite.loading || !!inviteDisableMessage" (click)="openInviteModal()">
<icon name="person_add" [flex]="true" type="filled"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">Invite to join</span>
</button>
<button *ngIf="!exists && isPortalAdmin" class="uk-button uk-button-default uk-flex uk-flex-middle"
(click)="openCreateRoleModal()">
<icon name="person_add" [flex]="true" type="filled"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">Create Group</span>
</button>
</div>
</div>
<div *ngIf="loading" class="uk-position-center">
<loading></loading>
</div>
<div *ngIf="!loading">
<div *ngIf="!loading" class="uk-section uk-section-small">
<div *ngIf="showSubscribers.length == 0"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div>No subscribers found</div>
<div>No members found</div>
</div>
<div *ngIf="showSubscribers.length > 0">
<no-load-paging [type]="(subscribers.length > 1)?'subscribers':'subscriber'"
<no-load-paging [type]="(subscribers.length > 1)?'members':'member'"
(pageChange)="updatePage($event)"
[page]="page" [pageSize]="pageSize"
[totalResults]="showSubscribers.length">
</no-load-paging>
<div class="uk-margin-top uk-margin-medium-bottom">
<div class="uk-card uk-card-default uk-card-body uk-text-small uk-margin-bottom"
*ngFor="let item of currentPage">
<div class="uk-grid uk-grid-divider uk-flex uk-flex-middle" uk-grid>
<div class="uk-width-expand@m uk-width-1-1">
<div class="uk-padding-small uk-padding-remove-horizontal">
<span class="uk-text-muted">Email: </span>
<span class="uk-text-bold">{{item.email}}</span>
</div>
<div class="uk-grid uk-grid-large uk-child-width-1-1@s uk-child-width-1-2@m uk-margin-top uk-margin-bottom" uk-grid>
<div *ngFor="let item of currentPage">
<div class="uk-card uk-card-default">
<div class="uk-card-body">
<span class="uk-text-bold uk-text-large">{{item.email}}</span>
</div>
<div class="uk-width-auto@m uk-width-1-1">
<div class="uk-width-1-1 uk-flex uk-flex-center">
<div class="uk-padding-small uk-padding-remove-horizontal">
<button (click)="openDeleteModal(item)" class="uk-button action uk-flex uk-flex-middle"
[disabled]="item.isManager"
[attr.uk-tooltip]="item.isManager?'This user is a manager and cannot be removed.':null">
<icon name="remove_circle_outline" [flex]="true"></icon>
<span class="uk-margin-small-left">Remove subscriber</span>
</button>
</div>
</div>
<div class="uk-card-footer uk-flex uk-flex-right">
<button (click)="openDeleteModal(item)" class="uk-button uk-button-link uk-flex uk-flex-middle"
[disabled]="item.isManager" [attr.uk-tooltip]="item.isManager?'This user is a manager and cannot be removed.':null">
<icon name="delete" [flex]="true" type="filled"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">{{'Delete'}}</span>
</button>
</div>
</div>
</div>
</div>
<no-load-paging *ngIf="showSubscribers.length > pageSize" [type]="'subscribers'"
(pageChange)="updatePage($event)"
[page]="page" [pageSize]="pageSize"
[totalResults]="showSubscribers.length">
</no-load-paging>
<div class="uk-flex uk-flex-right uk-margin-small-top">
<paging-no-load [currentPage]="page"
customClasses="uk-margin-remove-bottom"
[totalResults]="subscribers.length" [size]="pageSize"
(pageChange)="updatePage($event)">
</paging-no-load>
</div>
</div>
</div>
</div>
@ -83,20 +69,17 @@
</modal-alert>
<modal-alert #deleteModal [overflowBody]="false" (alertOutput)="deleteSubscriber()" classTitle="uk-background-primary uk-light">
<div *ngIf="selectedUser">
Are you sure you want to remove <span class="uk-text-bold">{{selectedUser}}</span> from subscribers?
Are you sure you want to remove <span class="uk-text-bold">{{selectedUser}}</span> from members?
</div>
</modal-alert>
<modal-alert #createRoleModal (alertOutput)="createGroup()" classTitle="uk-background-primary uk-light"
[okDisabled]="roleFb && roleFb.invalid">
<div *ngIf="roleFb" class="uk-padding uk-padding-remove-horizontal">
<div *ngIf="roleFb">
<div class="uk-grid" uk-grid [formGroup]="roleFb">
<div dashboard-input [formInput]="roleFb.get('name')"
label="Name"
placeholder="Write a name..." class="uk-width-1-1"></div>
<div dashboard-input [formInput]="roleFb.get('description')"
label="Description"
type="textarea"
placeholder="Write a description..." class="uk-width-1-1"></div>
<div input [formInput]="roleFb.get('name')"
placeholder="Name" class="uk-width-1-1"></div>
<div input [formInput]="roleFb.get('description')" type="textarea"
placeholder="Description" class="uk-width-1-1"></div>
</div>
</div>
</modal-alert>

View File

@ -1,10 +1,10 @@
import {
ChangeDetectorRef,
Component,
Component, EventEmitter,
Input,
OnChanges,
OnDestroy,
OnInit,
OnInit, Output,
SimpleChanges,
ViewChild
} from '@angular/core';
@ -39,6 +39,8 @@ export class SubscribersComponent implements OnInit, OnDestroy, OnChanges {
public message: string = null;
@Input()
public inviteDisableMessage: string;
@Output()
public stickyEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
public user: User = null;
public subscribers: any[];
public showSubscribers: any[];
@ -50,7 +52,7 @@ export class SubscribersComponent implements OnInit, OnDestroy, OnChanges {
public roleFb: FormGroup;
/** Paging */
page: number = 1;
pageSize: number = 5;
pageSize: number = 10;
/** Search */
filterForm: FormGroup;
@ViewChild('inviteModal') inviteModal: AlertModal;
@ -70,7 +72,9 @@ export class SubscribersComponent implements OnInit, OnDestroy, OnChanges {
keyword: this.fb.control('')
});
this.subs.push(this.filterForm.get('keyword').valueChanges.subscribe(value => {
this.filterBySearch(value);
if(this.subscribers) {
this.filterBySearch(value);
}
}));
this.updateList();
this.userManagementService.getUserInfo().subscribe(user => {
@ -120,13 +124,13 @@ export class SubscribersComponent implements OnInit, OnDestroy, OnChanges {
openDeleteModal(item: any) {
this.selectedUser = item.email;
this.deleteModal.alertTitle = 'Delete subscriber';
this.deleteModal.alertTitle = 'Delete member';
this.deleteModal.open();
}
openInviteModal() {
if(this.subscriberInvite && !this.subscriberInvite.loading) {
this.inviteModal.alertTitle = 'Invite users to subscribe';
this.inviteModal.alertTitle = 'Invite users to join ' + this.name;
this.inviteModal.okButtonLeft = false;
this.inviteModal.okButtonText = 'Send';
this.subscriberInvite.reset();

View File

@ -11,9 +11,10 @@ import {SafeHtmlPipeModule} from "../../../utils/pipes/safeHTMLPipe.module";
import {NoLoadPaging} from "../../../searchPages/searchUtils/no-load-paging.module";
import {SearchInputModule} from "../../../sharedComponents/search-input/search-input.module";
import {SubscriberInviteModule} from "../../../sharedComponents/subscriber-invite/subscriber-invite.module";
import {PagingModule} from "../../../utils/paging.module";
@NgModule({
imports: [CommonModule, AlertModalModule, ReactiveFormsModule, LoadingModule, IconsModule, InputModule, PageContentModule, SafeHtmlPipeModule, NoLoadPaging, SearchInputModule, SubscriberInviteModule],
imports: [CommonModule, AlertModalModule, ReactiveFormsModule, LoadingModule, IconsModule, InputModule, PageContentModule, SafeHtmlPipeModule, NoLoadPaging, SearchInputModule, SubscriberInviteModule, PagingModule],
declarations: [SubscribersComponent],
exports: [SubscribersComponent]
})

View File

@ -23,7 +23,7 @@ declare var UIkit;
</div>
</ng-template>
<ng-template [ngIf]="form.get('groups') && availableGroups">
<div #recipients input type="chips" [options]="availableGroups" [showOptionsOnEmpty]="false"
<div #recipients input type="chips" [options]="availableGroups"
placeholder="Sent to:" hint="Add a recipient" inputClass="recipients" [formInput]="form.get('groups')">
</div>
<div class="uk-position-relative uk-margin-medium-top">

View File

@ -100,7 +100,7 @@ declare var UIkit;
<div class="uk-label uk-label-small uk-flex uk-flex-middle"
[attr.uk-tooltip]="(tooltip)?('title: ' + getLabel(chip.value) + '; delay: 500; pos: bottom-left'):null">
<span class="uk-text-truncate uk-width-expand">{{getLabel(chip.value)}}</span>
<icon (click)="remove(i, $event)" class="uk-link-text uk-margin-small-left clickable" [flex]="true"
<icon [class.uk-invisible]="!focused" (click)="remove(i, $event)" class="uk-link-text uk-margin-small-left clickable" [flex]="true"
name="close" ratio="0.7"></icon>
</div>
</div>
@ -309,7 +309,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
@HostListener('window:keydown.enter', ['$event'])
enter(event: KeyboardEvent) {
if (this.opened) {
if (this.opened && this.optionBox) {
event.preventDefault();
if (this.filteredOptions[this.selectedIndex]) {
this.selectOption(this.filteredOptions[this.selectedIndex], event);
@ -483,7 +483,7 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang
add(event) {
if (this.addExtraChips && this.searchControl.value && this.searchControl.valid) {
if (event) {
if (event && event.stopPropagation) {
event.stopPropagation();
}
this.formAsArray.push(new FormControl(this.searchControl.value, this.validators));

View File

@ -17,24 +17,17 @@ declare var UIkit;
selector: 'subscriber-invite',
template: `
<div *ngIf="longView" class="uk-grid uk-child-width-1-1" uk-grid [formGroup]="inviteForm">
<div dashboard-input [formInput]="inviteForm.get('name')" [gridSmall]="true">
<div class="uk-text-bold field-label">
From:
</div>
<div input [formInput]="inviteForm.get('name')" placeholder="From"></div>
<div input [formInput]="inviteForm.get('recipients')" type="chips"
placeholder="Recipients" hint="Add a recipient"
[addExtraChips]="true" [validators]="validators">
</div>
<div dashboard-input [formInput]="inviteForm.get('recipients')" type="chips" placeholder="Write email(s)" [addExtraChips]="true" [validators]="validators" [gridSmall]="true">
<div class="uk-text-bold field-label">
To *:
</div>
</div>
<div class="uk-grid uk-grid-small" uk-grid>
<div class="uk-text-bold field-label">
Message *:
</div>
<div class="uk-width-expand">
<div>
<label class="uk-text-meta">Message *</label>
<div class="uk-margin-small-top">
<ckeditor *ngIf="isManager" class="form-control" formControlName="message" id="message"
debounce="400" (ready)="loading = false"
[config]="{ extraAllowedContent: '* [uk-*](*) ; span', disallowedContent: 'script; *[on*]',
[config]="{ extraAllowedContent: '* [uk-*](*) ; span', disallowedContent: 'script; *[on*]',
removeButtons: 'Save,NewPage,DocProps,Preview,Print,' +
'Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,' +
'CreateDiv,Flash,PageBreak,' +
@ -71,7 +64,7 @@ export class SubscriberInviteComponent implements OnInit, OnDestroy {
public inviteForm: FormGroup;
public email: Email;
public body: Body;
public validators: ValidatorFn[] = [Validators.email, Validators.required];
public validators: ValidatorFn[] = [Validators.email];
public loading: boolean = true;
private subscriptions: any[] = [];

View File

@ -188,8 +188,7 @@ export class Composer {
// TODO remove this after adding this on admin
public static initializeInvitationsBody(communityId: string, communityTitle: string, fullname: string): Body {
let body: Body = new Body();
let defaultMainBody = '<p>You are invited to subscribe to <a href="https://' + (properties.environment == "production"?'':'beta.') + communityId + '.openaire.eu/">'
let defaultMainBody = '<p>You are invited to join <a href="https://' + (properties.environment == "production"?'':'beta.') + communityId + '.openaire.eu/">'
+ communityTitle + '</a> dashboard.<br>';
if(communityId !== 'covid-19') {
defaultMainBody += 'The purpose of this dashboard is to gather, link &amp; monitor the research results related to your community.</p>'
@ -209,13 +208,13 @@ export class Composer {
'<p>The community dashboard is part of the<a href="https://connect.openaire.eu/"> OpenAIRE-Connect</a> project.</p>'
}
return body = {fromMessage: ", on behalf of ", fromName: fullname, paragraphs: defaultMainBody, signature: this.closing, note: ""};
return {fromMessage: ", on behalf of ", fromName: fullname, paragraphs: defaultMainBody, signature: this.closing, note: ""};
}
public static initializeInvitationsEmail(communityTitle: string) {
let email: Email = new Email();
return email = {body: "", subject: this.subjectPrefix + communityTitle, recipients: []};
return {body: "", subject: this.subjectPrefix + communityTitle, recipients: []};
}
public static composeEmailForMonitorDashboard(name: string, recipient: string, role: "manager" | "member") {