Project

General

Profile

« Previous | Next » 

Revision 60274

[Library | Trunk]: Create subscriber invite and subscribers components.

View differences:

modules/uoa-services-library/trunk/ng-openaire-library/src/app/dashboard/users/role-users/role-users.component.html
12 12
          </li>
13 13
        </ul>
14 14
      </div>
15
      <div [class.uk-invisible]="loadActive || loadPending" class="uk-width-1-5@l uk-width-1-3@m uk-width-1-1 uk-flex uk-flex-right@m uk-flex-center">
15
      <div [class.uk-invisible]="loadActive || loadPending"
16
           class="uk-width-1-5@l uk-width-1-3@m uk-width-1-1 uk-flex uk-flex-right@m uk-flex-center">
16 17
        <a *ngIf="exists" class="uk-text-uppercase uk-flex uk-flex-middle" (click)="openInviteModal()">
17 18
          <button class="uk-icon-button large uk-button-secondary">
18 19
            <icon name="person_add"></icon>
19 20
          </button>
20 21
          <button class="uk-button uk-button-link uk-margin-small-left uk-text-secondary">Invite {{role}}</button>
21 22
        </a>
22
        <a *ngIf="!exists && isPortalAdmin" class="uk-text-uppercase uk-flex uk-flex-middle" (click)="openCreateRoleModal()">
23
        <a *ngIf="!exists && isPortalAdmin" class="uk-text-uppercase uk-flex uk-flex-middle"
24
           (click)="openCreateRoleModal()">
23 25
          <button class="uk-icon-button large uk-button-secondary">
24 26
            <icon name="person_add"></icon>
25 27
          </button>
......
32 34
    <div *ngIf="loadActive || loadPending" class="uk-margin-large-top">
33 35
      <loading></loading>
34 36
    </div>
35
    <div *ngIf="!loadActive && !loadPending" class="uk-margin-medium-top">
37
    <div *ngIf="!loadActive && !loadPending">
36 38
      <div *ngIf="(showActive && active.length == 0) || (!showActive && pending.length == 0)"
37 39
           class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
38 40
        <div *ngIf="showActive">No {{role}}s for {{name}}</div>
modules/uoa-services-library/trunk/ng-openaire-library/src/app/dashboard/users/role-users/role-users.component.ts
8 8
import {Session, User} from "../../../login/utils/helper.class";
9 9
import {UserManagementService} from "../../../services/user-management.service";
10 10
import {Router} from "@angular/router";
11
import {LoginErrorCodes} from "../../../login/utils/guardHelper.class";
12
import {Composer} from "../../../utils/email/composer";
13 11
import {StringUtils} from "../../../utils/string-utils.class";
14 12

  
15 13
declare var UIkit;
modules/uoa-services-library/trunk/ng-openaire-library/src/app/dashboard/users/role-users/role-users.module.ts
2 2
import {CommonModule} from '@angular/common';
3 3
import {RoleUsersComponent} from './role-users.component';
4 4
import {ReactiveFormsModule} from '@angular/forms';
5
import {EmailService} from "../../../utils/email/email.service";
6 5
import {AlertModalModule} from "../../../utils/modal/alertModal.module";
7 6
import {LoadingModule} from "../../../utils/loading/loading.module";
8 7
import {IconsService} from "../../../utils/icons/icons.service";
......
15 14
@NgModule({
16 15
  imports: [CommonModule, AlertModalModule, ReactiveFormsModule, LoadingModule, IconsModule, InputModule, PageContentModule, SafeHtmlPipeModule],
17 16
  declarations: [RoleUsersComponent],
18
  exports: [RoleUsersComponent],
19
  providers: [EmailService]
17
  exports: [RoleUsersComponent]
20 18
})
21 19
export class RoleUsersModule {
22 20
  constructor(private iconsService: IconsService) {
modules/uoa-services-library/trunk/ng-openaire-library/src/app/dashboard/users/subscribers/subscribers.module.ts
1
import {NgModule} from '@angular/core';
2
import {CommonModule} from '@angular/common';
3
import {SubscribersComponent} from './subscribers.component';
4
import {ReactiveFormsModule} from '@angular/forms';
5
import {AlertModalModule} from "../../../utils/modal/alertModal.module";
6
import {LoadingModule} from "../../../utils/loading/loading.module";
7
import {IconsService} from "../../../utils/icons/icons.service";
8
import {person_add, remove_circle_outline} from "../../../utils/icons/icons";
9
import {IconsModule} from "../../../utils/icons/icons.module";
10
import {InputModule} from "../../../sharedComponents/input/input.module";
11
import {PageContentModule} from "../../sharedComponents/page-content/page-content.module";
12
import {SafeHtmlPipeModule} from "../../../utils/pipes/safeHTMLPipe.module";
13
import {NoLoadPaging} from "../../../searchPages/searchUtils/no-load-paging.module";
14
import {SearchInputModule} from "../../../sharedComponents/search-input/search-input.module";
15
import {SubscriberInviteModule} from "../../../sharedComponents/subscriber-invite/subscriber-invite.module";
16

  
17
@NgModule({
18
  imports: [CommonModule, AlertModalModule, ReactiveFormsModule, LoadingModule, IconsModule, InputModule, PageContentModule, SafeHtmlPipeModule, NoLoadPaging, SearchInputModule, SubscriberInviteModule],
19
  declarations: [SubscribersComponent],
20
  exports: [SubscribersComponent]
21
})
22
export class SubscribersModule {
23
  constructor(private iconsService: IconsService) {
24
    this.iconsService.registerIcons([remove_circle_outline, person_add]);
25
  }
26
}
modules/uoa-services-library/trunk/ng-openaire-library/src/app/dashboard/users/subscribers/subscribers.component.html
1
<div page-content>
2
  <div header>
3
    <ng-content></ng-content>
4
    <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>
5
      <div search-input [control]="filterForm.controls.keyword" [showSearch]="false" placeholder="Search"
6
           [bordered]="true" colorClass="uk-text-secondary" toggleTitle="locate subscribers"></div>
7
      <div>
8
        <a *ngIf="exists" class="uk-text-uppercase uk-flex uk-flex-middle" [class.uk-disabled]="!subscriberInvite || subscriberInvite.loading" (click)="openInviteModal()">
9
          <button class="uk-icon-button large uk-button-secondary">
10
            <icon name="person_add"></icon>
11
          </button>
12
          <button class="uk-button uk-button-link uk-margin-small-left uk-text-secondary">Invite Subscribers</button>
13
        </a>
14
        <a *ngIf="!exists && isPortalAdmin" class="uk-text-uppercase uk-flex uk-flex-middle" (click)="openCreateRoleModal()">
15
          <button class="uk-icon-button large uk-button-secondary">
16
            <icon name="person_add"></icon>
17
          </button>
18
          <button class="uk-button uk-button-link uk-margin-small-left uk-text-secondary">Create Group</button>
19
        </a>
20
      </div>
21
    </div>
22
  </div>
23
  <div inner>
24
    <div *ngIf="loading" class="uk-margin-large-top">
25
      <loading></loading>
26
    </div>
27
    <div *ngIf="!loading">
28
      <div *ngIf="showSubscribers.length == 0"
29
           class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
30
        <div>No subscribers for {{name}}</div>
31
      </div>
32
      <div *ngIf="showSubscribers.length > 0">
33
        <no-load-paging *ngIf="showSubscribers.length > pageSize" [type]="'subscribers'"
34
                        (pageChange)="updatePage($event)"
35
                        [page]="page" [pageSize]="pageSize"
36
                        [totalResults]="showSubscribers.length">
37
        </no-load-paging>
38
        <div class="uk-margin-medium-top uk-margin-medium-bottom">
39
          <div class="uk-card uk-card-default uk-card-body uk-text-small uk-margin-bottom"
40
               *ngFor="let item of showSubscribers.slice((page - 1)*pageSize, page*pageSize)">
41
            <div class="uk-grid uk-grid-divider uk-flex uk-flex-middle" uk-grid>
42
              <div class="uk-width-3-4@l uk-width-1-2@m">
43
                <div class="uk-padding-small uk-padding-remove-horizontal">
44
                  <span class="uk-text-muted">Email: </span>
45
                  <span class="uk-text-bold">{{item.email}}</span>
46
                </div>
47
              </div>
48
              <div class="uk-width-expand">
49
                <div class="uk-padding-small uk-padding-remove-horizontal uk-flex uk-flex-center">
50
                  <a (click)="openDeleteModal(item)" class="uk-button action uk-flex uk-flex-middle">
51
                    <icon name="remove_circle_outline" ratio="0.7" [flex]="true"></icon>
52
                    <span class="uk-margin-small-left">Remove subscriber</span>
53
                  </a>
54
                </div>
55
              </div>
56
            </div>
57
          </div>
58
        </div>
59
        <no-load-paging *ngIf="showSubscribers.length > pageSize" [type]="'subscribers'"
60
                        (pageChange)="updatePage($event)"
61
                        [page]="page" [pageSize]="pageSize"
62
                        [totalResults]="showSubscribers.length">
63
        </no-load-paging>
64
      </div>
65
    </div>
66
  </div>
67
</div>
68
<modal-alert *ngIf="user" #inviteModal (alertOutput)="subscriberInvite.invite()" [okDisabled]="!subscriberInvite.valid" [large]="true">
69
  <div class="uk-padding uk-padding-remove-horizontal">
70
    <subscriber-invite #subscriberInvite [user]="user"></subscriber-invite>
71
  </div>
72
</modal-alert>
73
<modal-alert #deleteModal (alertOutput)="deleteSubscriber()">
74
  <div *ngIf="selectedUser" class="uk-padding-small uk-padding-remove-horizontal">
75
    Are you sure you want to remove <span class="uk-text-bold">{{selectedUser}}</span> from subscribers?
76
  </div>
77
</modal-alert>
78
<modal-alert #createRoleModal (alertOutput)="createGroup()" [okDisabled]="roleFb && roleFb.invalid">
79
  <div *ngIf="roleFb" class="uk-padding uk-padding-remove-horizontal">
80
    <div class="uk-grid" uk-grid [formGroup]="roleFb">
81
      <div dashboard-input [formInput]="roleFb.get('name')"
82
           label="Name"
83
           placeholder="Write a name..." class="uk-width-1-1"></div>
84
      <div dashboard-input [formInput]="roleFb.get('description')"
85
           label="Description"
86
           type="textarea"
87
           placeholder="Write a description..." class="uk-width-1-1"></div>
88
    </div>
89
  </div>
90
</modal-alert>
modules/uoa-services-library/trunk/ng-openaire-library/src/app/dashboard/users/subscribers/subscribers.component.ts
1
import {Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild} from '@angular/core';
2
import {Subscription} from 'rxjs/Rx';
3
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
4
import {AlertModal} from "../../../utils/modal/alert";
5
import {UserRegistryService} from "../../../services/user-registry.service";
6
import {EnvProperties} from "../../../utils/properties/env-properties";
7
import {properties} from "../../../../../environments/environment";
8
import {Session, User} from "../../../login/utils/helper.class";
9
import {UserManagementService} from "../../../services/user-management.service";
10
import {Router} from "@angular/router";
11
import {Composer} from "../../../utils/email/composer";
12
import {SubscriberInviteComponent} from "../../../sharedComponents/subscriber-invite/subscriber-invite.component";
13

  
14
declare var UIkit;
15

  
16
@Component({
17
  selector: 'subscribers',
18
  templateUrl: 'subscribers.component.html'
19
})
20
export class SubscribersComponent implements OnInit, OnDestroy, OnChanges {
21
  
22
  @Input()
23
  public id: string;
24
  @Input()
25
  public type: string;
26
  @Input()
27
  public name: string;
28
  @Input()
29
  public link: string;
30
  @Input()
31
  public message: string = null;
32
  public user: User = null;
33
  public subscribers: any[];
34
  public showSubscribers: any[];
35
  public subs: any[] = [];
36
  public loading: boolean = true;
37
  public selectedUser: string = null;
38
  public properties: EnvProperties = properties;
39
  public exists: boolean = true;
40
  public roleFb: FormGroup;
41
  /* Paging */
42
  page: number = 1;
43
  pageSize: number = 10;
44
  /* Search */
45
  filterForm: FormGroup;
46
  @ViewChild('inviteModal') inviteModal: AlertModal;
47
  @ViewChild('deleteModal') deleteModal: AlertModal;
48
  @ViewChild('createRoleModal') createRoleModal: AlertModal;
49
  @ViewChild('subscriberInvite') subscriberInvite: SubscriberInviteComponent;
50
  
51
  constructor(private userRegistryService: UserRegistryService,
52
              private userManagementService: UserManagementService,
53
              private router: Router,
54
              private fb: FormBuilder) {
55
  }
56
  
57
  ngOnInit() {
58
    this.filterForm = this.fb.group({
59
      keyword: this.fb.control('')
60
    });
61
    this.subs.push(this.filterForm.get('keyword').valueChanges.subscribe(value => {
62
      this.filterBySearch(value);
63
    }));
64
    this.updateList();
65
    this.userManagementService.getUserInfo().subscribe(user => {
66
      this.user = user;
67
    });
68
  }
69
  
70
  ngOnChanges(changes: SimpleChanges) {
71
    if (changes.role) {
72
      this.updateList();
73
    }
74
  }
75
  
76
  ngOnDestroy() {
77
    this.subs.forEach(sub => {
78
      if (sub instanceof Subscription) {
79
        sub.unsubscribe();
80
      }
81
    });
82
  }
83
  
84
  updateList() {
85
    this.loading = true;
86
    this.subs.push(this.userRegistryService.getActiveEmail(this.type, this.id, 'member').subscribe(users => {
87
      this.subscribers = users;
88
      this.filterBySearch(this.filterForm.value.keyword);
89
      this.loading = false;
90
      this.exists = true;
91
    }, error => {
92
      this.subscribers = [];
93
      this.showSubscribers = [];
94
      if (error.status === 404) {
95
        this.exists = false;
96
      }
97
      this.loading = false;
98
    }));
99
  }
100
  
101
  openDeleteModal(item: any) {
102
    this.selectedUser = item.email;
103
    this.deleteModal.alertTitle = 'Delete subscriber';
104
    this.deleteModal.open();
105
  }
106
  
107
  openInviteModal() {
108
    if(this.subscriberInvite && !this.subscriberInvite.loading) {
109
      this.inviteModal.alertTitle = 'Invite users to subscribe';
110
      this.inviteModal.okButtonLeft = false;
111
      this.inviteModal.okButtonText = 'Send';
112
      this.subscriberInvite.reset();
113
      this.inviteModal.open();
114
    }
115
  }
116
  
117
  openCreateRoleModal() {
118
    this.createRoleModal.alertTitle = 'Create group';
119
    this.createRoleModal.okButtonLeft = false;
120
    this.createRoleModal.okButtonText = 'create';
121
    this.roleFb = this.fb.group({
122
      name: this.fb.control(Session.mapType(this.type) + '.' + this.id, Validators.required),
123
      description: this.fb.control('', Validators.required)
124
    });
125
    setTimeout(() => {
126
      this.roleFb.get('name').disable();
127
    }, 0);
128
    this.createRoleModal.open();
129
  }
130
  
131
  deleteSubscriber() {
132
    this.loading = true;
133
    this.userRegistryService.remove(this.type, this.id, this.selectedUser, 'member').subscribe(() => {
134
      this.subscribers = this.subscribers.filter(user => user.email != this.selectedUser);
135
      this.filterBySearch(this.filterForm.value.keyword);
136
      this.userManagementService.updateUserInfo();
137
      UIkit.notification(this.selectedUser + ' <b>is no longer</b> subscribed to ' + this.name + ' Dashboard', {
138
        status: 'success',
139
        timeout: 6000,
140
        pos: 'bottom-right'
141
      });
142
      this.loading = false;
143
    }, error => {
144
      UIkit.notification('An error has occurred. Please try again later', {
145
        status: 'danger',
146
        timeout: 6000,
147
        pos: 'bottom-right'
148
      });
149
      this.loading = false;
150
    });
151
  }
152
  
153
  createGroup() {
154
    this.loading = true;
155
    this.roleFb.get('name').enable();
156
    this.userRegistryService.createRole(this.type, this.id, this.roleFb.value).subscribe(() => {
157
      UIkit.notification('Group has been <b> successfully created</b>', {
158
        status: 'success',
159
        timeout: 6000,
160
        pos: 'bottom-right'
161
      });
162
      this.updateList();
163
    }, error => {
164
      UIkit.notification('An error has occurred. Please try again later', {
165
        status: 'danger',
166
        timeout: 6000,
167
        pos: 'bottom-right'
168
      });
169
      this.loading = false;
170
    });
171
  }
172
  
173
  public get isPortalAdmin() {
174
    return Session.isPortalAdministrator(this.user) || Session.isCurator(this.type, this.user);
175
  }
176
  
177
  public updatePage($event) {
178
    this.page = $event.value;
179
  }
180
  
181
  private filterBySearch(value: any) {
182
    this.showSubscribers = this.subscribers.filter(subscriber => !value || subscriber.email.includes(value));
183
  }
184
}
modules/uoa-services-library/trunk/ng-openaire-library/src/app/connect/community/community.service.ts
1
import { Injectable } from '@angular/core';
1
import {Injectable} from '@angular/core';
2 2
import {HttpClient, HttpHeaders} from "@angular/common/http";
3
import { CommunityInfo } from './communityInfo';
3
import {CommunityInfo} from './communityInfo';
4 4
import {EnvProperties} from '../../utils/properties/env-properties';
5 5
import {map} from "rxjs/operators";
6 6
import {BehaviorSubject, from, Subscriber} from "rxjs";
7 7
import {properties} from "../../../../environments/environment";
8
import {HelperFunctions} from "../../utils/HelperFunctions.class";
8 9

  
9
@Injectable({  providedIn: 'root' })
10
@Injectable({providedIn: 'root'})
10 11
export class CommunityService {
11

  
12
  
12 13
  public community: BehaviorSubject<CommunityInfo> = null;
13 14
  private promise: Promise<boolean> = null;
14

  
15
  private sub;
16
  
15 17
  constructor(private http: HttpClient) {
16 18
    this.community = new BehaviorSubject(null);
17 19
  }
18
  sub;
20
  
19 21
  ngOnDestroy() {
20 22
    this.clearSubscriptions();
21 23
  }
22
  clearSubscriptions(){
24
  
25
  clearSubscriptions() {
23 26
    if (this.sub instanceof Subscriber) {
24 27
      this.sub.unsubscribe();
25 28
    }
26 29
  }
30
  
31
  // TODO Remove these functions
27 32
  getCommunityByService(properties: EnvProperties, url: string) {
28 33
    this.promise = new Promise<any>(resolve => {
29 34
      this.sub = this.getCommunity(properties, url).subscribe(res => {
30
        this.community.next(res);
31
        resolve();
32
      },
33
      error => {
34
        this.community.error(error);
35
        resolve();
36
      })
35
          this.community.next(res);
36
          resolve();
37
        },
38
        error => {
39
          this.community.error(error);
40
          resolve();
41
        })
37 42
    });
38 43
  }
39

  
40
  async  getCommunityByStateAsync(properties: EnvProperties, url: string) {
41
    if(!this.promise) {
44
  
45
  async getCommunityByStateAsync(properties: EnvProperties, url: string) {
46
    if (!this.promise) {
42 47
      this.getCommunityByService(properties, url);
43 48
    }
44

  
49
    
45 50
    await this.promise;
46 51
    this.clearSubscriptions();
47 52
    return this.community.getValue();
48 53
  }
49

  
54
  
55
  public getCommunityAsObservable() {
56
    return this.community.asObservable();
57
  }
58
  
59
  setCommunity(community: CommunityInfo) {
60
    this.community.next(community);
61
  }
62
  
63
  private formalize(element: any) {
64
    return HelperFunctions.copy(element);
65
  }
66
  
50 67
  getCommunityByState(properties: EnvProperties, url: string) {
51 68
    return from(this.getCommunityByStateAsync(properties, url));
52 69
  }
53

  
70
  
54 71
  getCommunity(properties: EnvProperties, url: string) {
55
      return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
56
                      .pipe(map(res => this.parseCommunity(res)));
72
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
73
      .pipe(map(res => this.parseCommunity(res)));
57 74
  }
58

  
75
  
76
  // TODO remove NEW from function names
77
  getCommunityNew(communityId: string) {
78
    if(!this.community.value || this.community.value.communityId !== communityId) {
79
      this.promise = new Promise<any>((resolve, reject) => {
80
        this.sub = this.http.get<CommunityInfo>(properties.communityAPI + communityId)
81
          .pipe(map(community => this.formalize(this.parseCommunity(community)))).subscribe(community => {
82
              this.community.next(community);
83
              resolve();
84
            },
85
            error => {
86
              this.community.next(null);
87
              reject();
88
            })
89
      });
90
    }
91
    return from(this.getCommunityAsync());
92
  }
93
  
94
  async getCommunityAsync() {
95
    await this.promise;
96
    this.clearSubscriptions();
97
    return this.community.getValue();
98
  }
99
  
59 100
  updateCommunity(url: string, community: any) {
60
      //const headers = new Headers({'Content-Type': 'application/json'});
61
      //const options = new RequestOptions({headers: headers});
62

  
63
      const options = {
64
        headers: new HttpHeaders({
65
          'Content-Type': 'application/json',
66
        })
67
      };
68

  
69
      const body = JSON.stringify(community);
70
      return this.http.post(url, body, options);
71
                        /*.map(res => res.json())*/
101
    //const headers = new Headers({'Content-Type': 'application/json'});
102
    //const options = new RequestOptions({headers: headers});
103
    
104
    const options = {
105
      headers: new HttpHeaders({
106
        'Content-Type': 'application/json',
107
      })
108
    };
109
    
110
    const body = JSON.stringify(community);
111
    return this.http.post(url, body, options);
112
    /*.map(res => res.json())*/
72 113
  }
73

  
114
  
74 115
  async isCommunityManagerByStateAsync(properties: EnvProperties, url: string, manager: string) {
75
    if(!this.promise) {
116
    if (!this.promise) {
76 117
      this.getCommunityByService(properties, url);
77 118
    }
78

  
119
    
79 120
    await this.promise;
80 121
    let community: CommunityInfo = this.community.getValue();
81 122
    return (community.managers.indexOf(manager) !== -1);
82 123
  }
83

  
124
  
84 125
  isCommunityManagerByState(properties: EnvProperties, url: string, manager: string) {
85 126
    return from(this.isCommunityManagerByStateAsync(properties, url, manager));
86 127
  }
87

  
128
  
88 129
  /**
89 130
   * @deprecated
90 131
   */
91 132
  isCommunityManager(properties: EnvProperties, url: string, manager: string) {
92 133
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
93
                    //.map(res => <any> res.json())
94
                    .pipe(map(res => this.parseCommunity(res)))
95
                    .pipe(map(community => community.managers.indexOf(manager) !== -1));
134
      //.map(res => <any> res.json())
135
      .pipe(map(res => this.parseCommunity(res)))
136
      .pipe(map(community => community.managers.indexOf(manager) !== -1));
96 137
  }
97

  
138
  
98 139
  async isTypeByStateAsync(properties: EnvProperties, url: string, type: string) {
99
    if(!this.promise) {
140
    if (!this.promise) {
100 141
      this.getCommunityByService(properties, url);
101 142
    }
102

  
143
    
103 144
    await this.promise;
104 145
    let community: CommunityInfo = this.community.getValue();
105 146
    return (community && community.type && community.type === type);
106 147
  }
107

  
148
  
108 149
  isRITypeByState(properties: EnvProperties, url: string) {
109 150
    return from(this.isTypeByStateAsync(properties, url, "ri"));
110 151
  }
111

  
152
  
112 153
  isCommunityTypeByState(properties: EnvProperties, url: string) {
113 154
    return from(this.isTypeByStateAsync(properties, url, "community"));
114 155
  }
115

  
156
  
116 157
  /**
117 158
   * @deprecated
118 159
   */
119 160
  isRIType(properties: EnvProperties, url: string) {
120 161
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
121
        //.map(res => <any> res.json())
122
        .pipe(map(res => this.parseCommunity(res)))
123
        .pipe(map(community => (community && community.type && community.type === 'ri')));
162
      //.map(res => <any> res.json())
163
      .pipe(map(res => this.parseCommunity(res)))
164
      .pipe(map(community => (community && community.type && community.type === 'ri')));
124 165
  }
125

  
166
  
126 167
  /**
127 168
   * @deprecated
128 169
   */
129 170
  isCommunityType(properties: EnvProperties, url: string) {
130
      return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
131
          //.map(res => <any> res.json())
132
          .pipe(map(res => this.parseCommunity(res)))
133
          .pipe(map(community => (community && community.type && community.type === 'community')));
171
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
172
      //.map(res => <any> res.json())
173
      .pipe(map(res => this.parseCommunity(res)))
174
      .pipe(map(community => (community && community.type && community.type === 'community')));
134 175
  }
135

  
176
  
136 177
  /**
137
  * @deprecated
138
  */
178
   * @deprecated
179
   */
139 180
  isSubscribedToCommunity(pid: string, email: string, url: string) {
140
    return this.http.get(url + '/'+ properties.adminToolsPortalType +'/' + pid + '/subscribers')
141
                    //.map(res =>  ((<any>res === '') ? {} : <any> res.json()))
142
                    .pipe(map(res => {
143
                      if (res['subscribers'] && res['subscribers'] != null) {
144

  
145
                        for (let i = 0; i < res['subscribers'].length; i++ ) {
146
                          if (res['subscribers'][i] != null && res['subscribers'][i].email === email) {
147
                            return true;
148
                          }
149
                        }
150
                      }
151
                      return false;
152

  
153
                    }));
181
    return this.http.get(url + '/' + properties.adminToolsPortalType + '/' + pid + '/subscribers')
182
      //.map(res =>  ((<any>res === '') ? {} : <any> res.json()))
183
      .pipe(map(res => {
184
        if (res['subscribers'] && res['subscribers'] != null) {
185
          
186
          for (let i = 0; i < res['subscribers'].length; i++) {
187
            if (res['subscribers'][i] != null && res['subscribers'][i].email === email) {
188
              return true;
189
            }
190
          }
191
        }
192
        return false;
193
        
194
      }));
154 195
  }
155

  
196
  
156 197
  private parseCommunity(data: any): CommunityInfo {
157

  
158
      const resData = Array.isArray(data) ? data[0] : data;
159

  
160
      const community: CommunityInfo = new CommunityInfo();
161
      community['title'] = resData.name;
162
      community['shortTitle'] = resData.shortName;
163
      community['communityId'] = resData.id;
164
      community['queryId'] = resData.queryId;
165
      community['logoUrl'] = resData.logoUrl;
166
      community['description'] = resData.description;
167
      community['date'] = resData.creationDate;
168
      community['zenodoCommunity'] = resData.zenodoCommunity;
169
      community['status'] = 'all';
170
      if (resData.hasOwnProperty('status')) {
171
        community['status'] = resData.status;
172
        const status = ['all', 'hidden', 'manager'];
173
        if (status.indexOf(community['status']) === -1) {
174
          community['status'] = 'hidden';
175
        }
198
    
199
    const resData = Array.isArray(data) ? data[0] : data;
200
    
201
    const community: CommunityInfo = new CommunityInfo();
202
    community['title'] = resData.name;
203
    community['shortTitle'] = resData.shortName;
204
    community['communityId'] = resData.id;
205
    community['queryId'] = resData.queryId;
206
    community['logoUrl'] = resData.logoUrl;
207
    community['description'] = resData.description;
208
    community['date'] = resData.creationDate;
209
    community['zenodoCommunity'] = resData.zenodoCommunity;
210
    community['status'] = 'all';
211
    if (resData.hasOwnProperty('status')) {
212
      community['status'] = resData.status;
213
      const status = ['all', 'hidden', 'manager'];
214
      if (status.indexOf(community['status']) === -1) {
215
        community['status'] = 'hidden';
176 216
      }
177
      if (resData.type != null) {
178
            community['type'] = resData.type;
217
    }
218
    if (resData.type != null) {
219
      community['type'] = resData.type;
220
    }
221
    
222
    if (resData.managers != null) {
223
      if (community['managers'] === undefined) {
224
        community['managers'] = new Array<string>();
179 225
      }
180

  
181
      if (resData.managers != null) {
182
          if (community['managers'] === undefined) {
183
            community['managers'] = new Array<string>();
184
          }
185

  
186
          const managers = resData.managers;
187
          const length = Array.isArray(managers) ? managers.length : 1;
188

  
189
          for (let i = 0; i < length; i++) {
190
            const manager = Array.isArray(managers) ? managers[i] : managers;
191
            community.managers[i] = manager;
192
          }
226
      
227
      const managers = resData.managers;
228
      const length = Array.isArray(managers) ? managers.length : 1;
229
      
230
      for (let i = 0; i < length; i++) {
231
        const manager = Array.isArray(managers) ? managers[i] : managers;
232
        community.managers[i] = manager;
193 233
      }
194

  
195
      if (resData.subjects != null) {
196
          if (community['subjects'] === undefined) {
197
            community['subjects'] = new Array<string>();
198
          }
199

  
200
          const subjects = resData.subjects;
201
          const length = Array.isArray(subjects) ? subjects.length : 1;
202

  
203
          for (let i = 0; i < length; i++) {
204
            const subject = Array.isArray(subjects) ? subjects[i] : subjects;
205
            community.subjects[i] = subject;
206
          }
234
    }
235
    
236
    if (resData.subjects != null) {
237
      if (community['subjects'] === undefined) {
238
        community['subjects'] = new Array<string>();
207 239
      }
208
      return community;
240
      
241
      const subjects = resData.subjects;
242
      const length = Array.isArray(subjects) ? subjects.length : 1;
243
      
244
      for (let i = 0; i < length; i++) {
245
        const subject = Array.isArray(subjects) ? subjects[i] : subjects;
246
        community.subjects[i] = subject;
247
      }
248
    }
249
    return community;
209 250
  }
210

  
251
  
211 252
}
modules/uoa-services-library/trunk/ng-openaire-library/src/app/utils/email/composer.ts
242 242
    email.recipient = recipient;
243 243
    return email;
244 244
  }
245
  
246
  public static composeEmailForCommunityDashboard(name: string, recipient: string, role: "manager" | "member") {
247
    let email: Email = new Email();
248
    email.subject = 'OpenAIRE Monitor Dashboard | ' + name;
249
    email.body = '<p>Dear ((__user__)),</p>' +
250
      '<p>You have been invited to be a ' + role +' of the OpenAIRE Monitor Dashboard for the ' + name + '.</p>' +
251
      '<p>Click <a href="((__link__))">this URL</a> and use the verification code below to accept the invitation.</p>' +
252
      '<p>The verification code is <b>((__code__))</b>.</p>' +
253
      (role === "manager"?
254
        '<p>As a manager of the OpenAIRE Monitor Dashboard, you will have access to the administration part of the dashboard, ' +
255
        'where you will be able to customize and manage the profile of the ' + name + '.</p>':
256
        '<p>As a member of the OpenAIRE Monitor Dashboard, you will have access to the restricted access areas of the profile for the ' + name + '.') +
257
      '<p>Please contact us at <a href="mailto:' + properties.helpdeskEmail+'">' +  properties.helpdeskEmail +
258
      '</a> if you have any questions or concerns.</p>' +
259
      '<p>Kind Regards<br>The OpenAIRE Team</p>' +
260
      '<p><a href="' + properties.domain + '">OpenAIRE Monitor</a></p>'
261
    email.recipient = recipient;
262
    return email;
263
  }
245 264
}
modules/uoa-services-library/trunk/ng-openaire-library/src/app/utils/string-utils.class.ts
1 1
import {UrlSegment} from '@angular/router';
2
import {ValidatorFn, Validators} from "@angular/forms";
2
import {AbstractControl, ValidatorFn, Validators} from "@angular/forms";
3 3

  
4 4
export class Dates {
5 5
  public static yearMin = 1800;
......
214 214
    return decodeURIComponent(params);
215 215
  }
216 216
  
217
  public static validateEmails(emails: string): boolean {
218
    return (emails.split(',')
219
      .map(email => Validators.email(<AbstractControl>{ value: email.trim() }))
220
      .find(_ => _ !== null) === undefined);
221
  }
222
  
217 223
  public static b64DecodeUnicode(str) {
218 224
    return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
219 225
      return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
modules/uoa-services-library/trunk/ng-openaire-library/src/app/sharedComponents/input/input.component.ts
17 17
  template: `
18 18
    <div *ngIf="label && type != 'checkbox'" class="uk-text-bold uk-form-label uk-margin-small-bottom">{{label + (required ? ' *' : '')}}</div>
19 19
    <div *ngIf="hint" class="uk-margin-bottom uk-text-small uk-form-hint">{{hint}}</div>
20
    <div class="uk-grid uk-flex uk-flex-middle" uk-grid>
20
    <div class="uk-grid uk-flex uk-flex-middle" [class.uk-grid-small]="gridSmall" uk-grid>
21 21
      <ng-content></ng-content>
22
      <div [class.uk-hidden]="hideControl" class="uk-width-expand@m uk-position-relative" [class.uk-flex-first]="!extraLeft">
22
      <div [class.uk-hidden]="hideControl" class="uk-width-expand uk-position-relative" [class.uk-flex-first]="!extraLeft">
23 23
        <ng-template [ngIf]="icon && formControl.enabled">
24 24
          <span class="uk-text-muted" [ngClass]="iconLeft?('left'):'right'">
25 25
            <icon [name]="icon"></icon>
......
52 52
            </mat-form-field>
53 53
          </div>
54 54
        </ng-template>
55
        <span *ngIf="formControl.invalid && formControl.errors.error" class="uk-text-small uk-text-danger">{{formControl.errors.error}}</span>
56
        <span *ngIf="warning" class="uk-text-small uk-text-warning">{{warning}}</span>
55
        <span *ngIf="formControl.invalid && formControl.errors.error" class="uk-text-danger input-message">{{formControl.errors.error}}</span>
56
        <span *ngIf="warning" class="uk-text-warning input-message">{{warning}}</span>
57
        <span *ngIf="note" class="input-message">{{note}}</span>
57 58
      </div>
58 59
    </div>
59 60
    <mat-checkbox *ngIf="type === 'checkbox'" [formControl]="formControl">{{label}}</mat-checkbox>
......
70 71
  @Input('placeholder') placeholder = '';
71 72
  @ViewChild('select') select: MatSelect;
72 73
  @Input() extraLeft: boolean = true;
74
  @Input() gridSmall: boolean = false;
73 75
  @Input() hideControl: boolean = false;
74 76
  @Input() icon: string = null;
75 77
  @Input() iconLeft: boolean = false;
76 78
  @Input() warning: string = null;
79
  @Input() note: string = null;
77 80
  public required: boolean = false;
78 81
  private initValue: any;
79 82
  private subscriptions: any[] = [];
modules/uoa-services-library/trunk/ng-openaire-library/src/app/sharedComponents/input/input.component.css
9 9
  transform: translateY(-50%);
10 10
}
11 11

  
12
.uk-grid-small .left {
13
  left: 20px;
14
}
15

  
12 16
.left + .input-box {
13 17
  padding-left: 41px;
14 18
}
......
23 27
.right + .input-box {
24 28
  padding-right: 41px;
25 29
}
30

  
31
.input-message {
32
  font-family: "Roboto", sans-serif;
33
  font-size: 14px;
34
}
modules/uoa-services-library/trunk/ng-openaire-library/src/app/sharedComponents/subscriber-invite/subscriber-invite.component.ts
1
import {Component, Input, OnDestroy, OnInit} from "@angular/core";
2
import {AbstractControl, FormBuilder, FormGroup, ValidationErrors, Validators} from "@angular/forms";
3
import {Subscriber} from "rxjs";
4
import {StringUtils} from "../../utils/string-utils.class";
5
import {Email} from "../../utils/email/email";
6
import {Body} from "../../utils/email/body";
7
import {CommunityService} from "../../connect/community/community.service";
8
import {Composer} from "../../utils/email/composer";
9
import {User} from "../../login/utils/helper.class";
10
import {EmailService} from "../../utils/email/email.service";
11
import {properties} from "../../../../environments/environment";
12

  
13
declare var UIkit;
14

  
15
@Component({
16
  selector: 'subscriber-invite',
17
  template: `
18
    <div class="uk-grid uk-child-width-1-1" uk-grid [formGroup]="inviteForm">
19
      <div dashboard-input [formInput]="inviteForm.get('name')" [gridSmall]="true">
20
        <div class="uk-text-bold field-label">
21
          From *:
22
        </div>
23
      </div>
24
      <div dashboard-input [formInput]="inviteForm.get('recipients')" [gridSmall]="true" note="Separate multiple emails with a comma">
25
        <div class="uk-text-bold field-label uk-margin-bottom">
26
          To *:
27
        </div>
28
      </div>
29
      <div class="uk-grid uk-grid-small" uk-grid>
30
        <div class="uk-text-bold field-label">
31
          Message *:
32
        </div>
33
        <div class="uk-width-expand">
34
          <ckeditor class="form-control" formControlName="message" id="message"
35
                    debounce="400"
36
                    [config]="{ extraAllowedContent: '* [uk-*](*) ; span', disallowedContent: 'script; *[on*]', removeButtons: 'Save,NewPage,DocProps,Preview,Print',
37
                                                                   extraPlugins: 'divarea'}"></ckeditor>
38
          <div class="uk-margin-top">
39
            {{body.signature}}
40
            <span *ngIf="body.fromName == ''" class="uk-text-muted">
41
              <i>{{body.fromMessage}}...</i>
42
            </span>
43
            <span *ngIf="body.fromName !=''">
44
              {{body.fromMessage}}
45
              <b>{{body.fromName}}</b>
46
            </span><br>
47
            <a href="https://www.openaire.eu">www.openaire.eu</a>
48
          </div>
49
        </div>
50
      </div>
51
    </div>
52
  `,
53
  styleUrls: ['subscriber-invite.component.css']
54
})
55
export class SubscriberInviteComponent implements OnInit, OnDestroy {
56
  @Input()
57
  public user: User;
58
  public inviteForm: FormGroup;
59
  public email: Email;
60
  public body: Body;
61
  public loading: boolean = false;
62
  private subscriptions: any[] = [];
63
  
64
  constructor(private fb: FormBuilder,
65
              private emailService: EmailService,
66
              private communityService: CommunityService) {
67
  }
68
  
69
  ngOnInit() {
70
    this.reset();
71
  }
72
  
73
  ngOnDestroy() {
74
    this.unsubscribe();
75
  }
76
  
77
  unsubscribe() {
78
    this.subscriptions.forEach(subscription => {
79
      if(subscription instanceof Subscriber) {
80
        subscription.unsubscribe();
81
      }
82
    });
83
  }
84
  
85
  reset() {
86
    this.unsubscribe();
87
    this.inviteForm = this.fb.group({
88
      name: this.fb.control('', Validators.required),
89
      recipients: this.fb.control('', [Validators.required, this.emailsValidator]),
90
      message: this.fb.control('', Validators.required)
91
    });
92
    this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(community => {
93
      this.inviteForm.get('name').enable();
94
      this.inviteForm.get('name').setValue(this.user.fullname);
95
      this.inviteForm.get('name').disable();
96
      this.body = Composer.initializeInvitationsBody(community.communityId, community.title, this.user.fullname);
97
      this.email = Composer.initializeInvitationsEmail(community.title);
98
      this.inviteForm.get('message').setValue(this.body.paragraphs);
99
    }));
100
  }
101
  
102
  emailsValidator(control: AbstractControl): ValidationErrors | null {
103
    if (control.value === '' || !control.value || StringUtils.validateEmails(control.value)) {
104
      return null;
105
    }
106
    return { emails: true };
107
  }
108
  
109
  invite() {
110
    this.loading = true;
111
    this.parseRecipients();
112
    this.body.paragraphs = this.inviteForm.value.message;
113
    this.email.body = Composer.formatEmailBodyForInvitation(this.body);
114
    this.subscriptions.push(this.emailService.sendEmail(properties, this.email).subscribe(res => {
115
      if(res['success']) {
116
        UIkit.notification('Invitation to subscribe has been <b>sent</b>', {
117
          status: 'success',
118
          timeout: 6000,
119
          pos: 'bottom-right'
120
        });
121
      } else {
122
        UIkit.notification('An error has occurred. Please try again later', {
123
          status: 'danger',
124
          timeout: 6000,
125
          pos: 'bottom-right'
126
        });
127
      }
128
      this.loading = false;
129
    },error => {
130
      UIkit.notification('An error has occurred. Please try again later', {
131
        status: 'danger',
132
        timeout: 6000,
133
        pos: 'bottom-right'
134
      });
135
      this.loading = false;
136
    }));
137
  }
138
  
139
  public parseRecipients() {
140
    // remove spaces
141
    let emails = this.inviteForm.get('recipients').value.replace(/\s/g, '');
142
    // remove commas
143
    emails = emails.split(",");
144
    
145
    // remove empty fields
146
    for (let i = 0; i < emails.length; i++) {
147
      if (!(emails[i] == "")) {
148
        this.email.recipients.push(emails[i]);
149
      }
150
    }
151
  }
152
  
153
  get valid() {
154
    return this.inviteForm && this.inviteForm.valid;
155
  }
156
}
modules/uoa-services-library/trunk/ng-openaire-library/src/app/sharedComponents/subscriber-invite/subscriber-invite.component.css
1
.field-label {
2
  width: 100px;
3
  text-align: right;
4
}
modules/uoa-services-library/trunk/ng-openaire-library/src/app/sharedComponents/subscriber-invite/subscriber-invite.module.ts
1
import {NgModule} from "@angular/core";
2
import {CommonModule} from "@angular/common";
3
import {SubscriberInviteComponent} from "./subscriber-invite.component";
4
import {InputModule} from "../input/input.module";
5
import {CKEditorModule} from "ng2-ckeditor";
6
import {ReactiveFormsModule} from "@angular/forms";
7
import {EmailService} from "../../utils/email/email.service";
8

  
9
@NgModule({
10
  imports: [CommonModule, InputModule, CKEditorModule, ReactiveFormsModule],
11
  declarations: [SubscriberInviteComponent],
12
  exports: [SubscriberInviteComponent],
13
  providers: [EmailService]
14
})
15
export class SubscriberInviteModule {
16

  
17
}
modules/uoa-services-library/trunk/ng-openaire-library/src/app/sharedComponents/search-input/search-input.component.ts
40 40
        <span [ngClass]="colorClass" class="icon-bg">
41 41
          <icon class="uk-position-center" name="search"></icon>
42 42
        </span>
43
        <span class="uk-text-uppercase overlay">search</span>
43
        <span class="uk-text-uppercase overlay">{{toggleTitle}}</span>
44 44
      </button>
45 45
      <button [disabled]="loading" class="search uk-flex uk-flex-middle uk-hidden@m"
46 46
              (mousedown)="$event.preventDefault()" (click)="search()">
47 47
        <span [ngClass]="colorClass" class="icon-bg">
48 48
          <icon class="uk-position-center" name="search"></icon>
49 49
        </span>
50
        <span class="uk-text-uppercase overlay">search</span>
50
        <span class="uk-text-uppercase overlay">{{toggleTitle}}</span>
51 51
      </button>
52 52
    </div>`
53 53
})
......
68 68
  colorClass: string = 'portal-color';
69 69
  @Input()
70 70
  bordered: boolean = false;
71
  @Input()
72
  toggleTitle: string = 'search';
71 73
  @ViewChild('input') input: ElementRef;
72 74
  @ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
73 75
  @Output()

Also available in: Unified diff