Project

General

Profile

« Previous | Next » 

Revision 60683

[new-UI | Admin]:
1. community-info-routing.module.ts: Added 'projects' path.
2. remove-projects.component.html & remove-projects.component.ts & add-projects.component.html & add-projects.component.ts & manage-projects.component.ts & communityProjects.module.ts:
Added projects folder for remove and add pages (both included in manage component).

View differences:

modules/uoa-admin-portal/branches/new-UI/src/app/pages/projects/add-projects.component.html
1
<div class="uk-width-1-1 uk-flex uk-flex-middle uk-grid uk-padding-small" uk-grid>
2
  <div *ngIf="funders?.length > 0"
3
       class="uk-width-1-2@m uk-width-1-1">
4
    <div class="uk-grid uk-flex uk-flex-middle uk-flex-wrap uk-flex-center uk-flex-right@m uk-width-1-1">
5
      <span class="">Filter by: </span>
6
      <div class="uk-width-expand uk-padding-remove uk-margin-small-left" dashboard-input
7
           [formInput]="filterForm.get('funder')"
8
           placeholder="Search by funders"
9
          type="autocomplete" [options]="allOptions" chipLabel="label">
10
      </div>
11
    </div>
12
  </div>
13
  <div class="uk-flex uk-flex-wrap uk-flex-center uk-flex-right@m uk-width-1-1 uk-width-expand@m">
14
    <div class="uk-width-1-1 uk-width-expand@m">
15
    <div #searchInputComponent search-input [control]="filterForm.controls.keyword" [showSearch]="false" placeholder="Search"
16
         [selected]="openaireSearchUtils.keyword" (closeEmitter)="onSearchClose()" (resetEmitter)="resetInput()"
17
         [bordered]="true" colorClass="uk-text-secondary" toggleTitle="locate projects"></div>
18
  </div>
19
  </div>
20
</div>
21

  
22
<!--<div class="uk-width-1-1 uk-flex uk-flex-right@m uk-flex-center uk-flex-wrap uk-flex-middle uk-grid" uk-grid>-->
23
<!--  <div #searchInputComponent search-input [control]="filterForm.controls.keyword" [showSearch]="false"-->
24
<!--       placeholder="Search Zenodo Communites"-->
25
<!--       [selected]="openaireSearchUtils.keyword"-->
26
<!--       [bordered]="true" colorClass="uk-text-secondary"-->
27
<!--       class="uk-width-1-2@l uk-width-1-2@m uk-width-1-1"></div>-->
28

  
29
<!--</div>-->
30

  
31
<div id="manage-projects" class="uk-padding-small">
32

  
33
<!--<div *ngIf="openaireSearchUtils.status == errorCodes.DONE" class="uk-alert uk-alert-primary">-->
34
<!--  <span class="uk-margin-small-right uk-icon" uk-icon="warning"></span>-->
35
<!--Newly added projects will be linked to your community on the next run of our algorithms.-->
36
<!--&lt;!&ndash; <div> If you cannot find a funder that is relevant for your community, please contact us (<a [href]="'mailto:' + properties.feedbackmailForMissingEntities +'?Subject=[OpenAIRE Connect - '+ community + '] report missing Funder' + '&body=' + body" target="_top">feedback@openaire.eu</a>) and we'll try to get the funder on board!</div> &ndash;&gt;-->
37
<!--</div>-->
38

  
39
<!--<div *ngIf="openaireSearchUtils.status == errorCodes.DONE" class="uk-alert uk-alert-primary">-->
40
<!--  <span class="uk-margin-small-right uk-icon" uk-icon="warning"></span>-->
41
<!--  If you cannot find a funder that is relevant for your community, please contact us (<a [href]="'mailto:' + properties.feedbackmailForMissingEntities +'?Subject=[OpenAIRE Connect - '+ community + '] report missing Funder' + '&body=' + body" target="_top">feedback@openaire.eu</a>) and we'll try to get the funder on board!-->
42
<!--</div>-->
43

  
44
<errorMessages [status]="[openaireSearchUtils.status]" [type]="'OpenAIRE projects'"></errorMessages>
45
<div *ngIf="openaireSearchUtils.status == errorCodes.NONE" class="uk-alert uk-alert-primary">
46
  <span class="uk-margin-small-right uk-icon" uk-icon="warning"></span>
47
   If you wish to suggest a new funder to include or report a missing project, please contact us via
48
   <a [href]="'mailto:' + properties.feedbackmailForMissingEntities +'?Subject=[OpenAIRE Connect - '+ community + '] report missing project' + '&body=' + body" target="_top">feedback@openaire.eu</a>.
49
</div>
50

  
51
<!--<div *ngIf="openaireSearchUtils.totalResults > 0" class="uk-align-center uk-margin-remove-bottom">-->
52
<!--  <div class="searchPaging uk-panel uk-margin-top uk-grid uk-margin-bottom">-->
53
<!--    <span class="uk-h6 uk-width-1-1@s uk-width-1-2@m">-->
54
<!--      {{openaireSearchUtils.totalResults | number}} projects, page {{openaireSearchUtils.page | number}} of {{(totalPages()) | number}}-->
55
<!--    </span>-->
56
<!--    <span class="float-children-right-at-medium margin-small-top-at-small uk-width-1-1@s uk-width-1-2@m">-->
57
<!--      <paging-no-load [limitPaging]=true [currentPage]="openaireSearchUtils.page" [totalResults]="openaireSearchUtils.totalResults" [size]="rowsOnPage" (pageChange)="goTo($event.value)"></paging-no-load>-->
58
<!--    </span>-->
59
<!--  </div>-->
60
<!--</div>-->
61

  
62
  <no-load-paging  *ngIf="openaireSearchUtils.totalResults > 0" [type]="'Projects'"
63
                   [page]="openaireSearchUtils.page" [pageSize]="rowsOnPage" (pageChange)="goTo($event.value)"
64
                   [totalResults]="openaireSearchUtils.totalResults" >
65
  </no-load-paging>
66

  
67
<ul class="uk-list search-results uk-margin-medium-top uk-margin-medium-bottom">
68
  <li *ngFor="let result of openaireProjects" class="uk-animation-fade">
69
    <div class="uk-card uk-card-default uk-card-hover uk-text-small uk-margin-bottom">
70
      <div class="uk-grid uk-grid-divider uk-flex uk-flex-middle" uk-grid>
71
        <div class="uk-width-expand@m uk-width-1-1">
72
          <result-preview [properties]="properties" [showOrganizations]="true"
73
                          [showSubjects]="true" [result]="getResultPreview(result)" [showImage]="true">
74
          </result-preview>
75
<!--        <div class="uk-padding-small uk-padding-remove-horizontal">-->
76
<!--          <h6>-->
77
<!--            <a target="_blank" [href]="properties.baseOpenaireLink+'/search/project?projectId='+result.id">-->
78
<!--               <span *ngIf="result['title'].name || result.acronym">-->
79
<!--                 <span *ngIf="result.acronym">{{result.acronym}}</span>-->
80
<!--                 <span *ngIf="result.acronym && result['title'].name">-</span>-->
81
<!--                 <span [innerHTML]="result['title'].name"></span>-->
82
<!--                 <span *ngIf="result.code">({{result.code}})</span>-->
83
<!--               </span>-->
84
<!--              <span *ngIf="!result['title'].name && !result.acronym">-->
85
<!--                 [no title available]-->
86
<!--                 <span *ngIf="result.code">({{result.code}})</span>-->
87
<!--              </span>-->
88
<!--              <span class="custom-external custom-icon space"></span>-->
89
<!--            </a>-->
90
<!--          </h6>-->
91
<!--          <span *ngIf="result.title && result.title.accessMode" [class]="'uk-label custom-label  label-'+ result.title.accessMode " title="Access Mode">{{result.title.accessMode}}</span>-->
92
<!--          <span *ngIf="result.funderShortname" class="uk-label custom-label label-funder " title="Funder">{{result.funderShortname}}</span>-->
93
<!--          <span *ngIf="result.title  && result.title.sc39" class="uk-label custom-label label-sc39 " title="Special Clause 39">Special Clause 39</span>-->
94

  
95
<!--          <div *ngIf="result.startYear && result.endYear"> Start year: {{result.startYear}} - End year: {{result.endYear}}</div>-->
96
<!--          <div *ngIf="result['organizations'] != undefined && result['organizations'].length > 0">-->
97
<!--            <span> Organization: </span>-->
98
<!--            <span *ngFor="let organization of result['organizations'].slice(0,10) let i=index">-->
99
<!--               <a *ngIf="organization.id" target="_blank"-->
100
<!--                  [href]="properties.baseOpenaireLink+'/search/organization?organizationId='+organization.id">-->
101
<!--                    <span>{{organization.name}}</span>-->
102
<!--                    <span class="custom-external custom-icon space"></span>-->
103
<!--               </a>-->
104
<!--             <span-->
105
<!--               *ngIf="!organization.id">-->
106
<!--                       {{organization.name}}</span><span-->
107

  
108
<!--              *ngIf="(i < result['organizations'].length-1) && (i < 9)">,</span>-->
109
<!--           </span>-->
110
<!--            <span *ngIf="result['organizations'].length > 10">...</span>-->
111
<!--          </div>-->
112
<!--        </div>-->
113
        </div>
114
        <div class="uk-width-auto@m uk-width-1-1">
115
          <div class="uk-flex uk-flex-middle uk-flex-center uk-flex-column uk-height-1-1">
116
            <div class="uk-padding-small uk-padding-remove-horizontal">
117

  
118
  <!--          <span *ngIf="inCommunity(result)" class="uk-label uk-label-success uk-flex uk-flex-middle">Added in my community</span>-->
119
              <div [class.hide-element]="!getCommunityProjectId(result)">
120
                <a (click)="removeProject(result)" class="uk-button action uk-flex uk-flex-middle">
121
                  <icon name="remove_circle_outline" ratio="0.7"></icon>
122
                  <span class="uk-margin-small-left">Remove project</span>
123
                </a>
124
              </div>
125

  
126
              <div [class.hide-element]="getCommunityProjectId(result)">
127
                <a (click)="addProject(result)" class="uk-button action uk-flex uk-flex-middle"
128
                   uk-tooltip="title:<div class='uk-padding-small'><div class='uk-margin-bottom uk-text-bold'>Add new project </div><div>Newly added projects will be linked to your community on the next run of our algorithms.</div></div>">
129
                  <div class="uk-text-success">
130
                    <icon name="add"></icon>
131
                  </div>
132
                  <span class="uk-margin-small-left">Add project</span>
133
                </a>
134
              </div>
135
  <!--          <a *ngIf="undo[result.id]" (click)="removeProject(undo[result.id], result.id)" -->
136
  <!--             class="uk-button action uk-flex uk-flex-middle">-->
137
  <!--            <icon name="remove_circle_outline" ratio="0.7" [flex]="true"></icon>-->
138
  <!--            <span class="uk-margin-small-left">Remove project</span>-->
139
  <!--          </a>-->
140
            </div>
141
          </div>
142
        </div>
143
      </div>
144
    </div>
145
  </li>
146
</ul>
147

  
148
<!--<ul *ngIf="(openaireSearchUtils.page <= pagingLimit)" [class]="'uk-list uk-list-divider  uk-margin '+custom_class">-->
149
<!-- &lt;!&ndash; <errorMessages [status]="[status]" [type]="'results'"></errorMessages> &ndash;&gt;-->
150

  
151
<!--   <li *ngFor="let result of openaireProjects" class="uk-animation-fade">-->
152
<!--       <h6 class="uk-grid" uk-grid>-->
153
<!--           <span class="uk-width-5-6">-->
154
<!--             <a target="_blank" [href]="properties.baseOpenaireLink+'/search/project?projectId='+result.id">-->
155
<!--               <span *ngIf="result['title'].name || result.acronym">-->
156
<!--                 <span *ngIf="result.acronym">{{result.acronym}}</span>-->
157
<!--                 <span *ngIf="result.acronym && result['title'].name">-</span>-->
158
<!--                 <span [innerHTML]="result['title'].name"></span>-->
159
<!--                 <span *ngIf="result.code">({{result.code}})</span>-->
160
<!--               </span>-->
161
<!--               <span *ngIf="!result['title'].name && !result.acronym">-->
162
<!--                 [no title available]-->
163
<!--                 <span *ngIf="result.code">({{result.code}})</span>-->
164
<!--              </span>-->
165
<!--               <span class="custom-external custom-icon space"></span>-->
166
<!--             </a>-->
167
<!--           </span>-->
168

  
169
<!--           <span class="uk-width-1-6 uk-text-center">-->
170
<!--             &lt;!&ndash; <a *ngIf="!inCommunity(result)" (click)="addProject(result)" class="uk-icon-button"><svg height="20" icon="plus" ratio="1" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><rect height="17" width="1" x="9" y="1"></rect><rect height="1" width="17" x="1" y="9"></rect></svg></a> &ndash;&gt;-->
171
<!--&lt;!&ndash;               green_background_color green_color&ndash;&gt;-->
172
<!--             <a *ngIf="!inCommunity(result)" (click)="addProject(result)" class="uk-icon-button add uk-button-primary" uk-icon="plus" title="Add"></a>-->
173

  
174
<!--             <span *ngIf="inCommunity(result)" class="uk-label uk-label-success">Added</span>-->
175
<!--             &lt;!&ndash; <svg *ngIf="inCommunity(result)" class="added" src="assets/imgs/check-icon.png" title="Added" width="20" type="image" height="20"></svg> &ndash;&gt;-->
176

  
177
<!--             &lt;!&ndash; <button *ngIf="undo[result.id]" class="uk-button uk-button-danger uk-button-small" (click)="removeProject(result.id)">Undo</button> &ndash;&gt;-->
178
<!--             &lt;!&ndash; <input *ngIf="undo[result.id]" (click)="removeProject(result.id)" class="remove" src="assets/imgs/x-icon.png" title="Undo" width="20" type="image" height="20"> &ndash;&gt;-->
179
<!--             &lt;!&ndash; <a *ngIf="undo[result.id]" (click)="removeProject(result.id)" class="remove red_colour"><svg height="20" icon="close" ratio="1" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><rect height="17" width="1" x="9" y="1"></rect><rect height="1" width="17" x="1" y="9"></rect></svg></a> &ndash;&gt;-->
180
<!--&lt;!&ndash;               red_background_color red_color&ndash;&gt;-->
181
<!--             <a *ngIf="undo[result.id]" (click)="removeProject(undo[result.id], result.id)" class="uk-icon-button remove uk-button-danger" uk-icon="close" title="Undo"></a>-->
182

  
183
<!--          </span>-->
184
<!--       </h6>-->
185
<!--       <span *ngIf="result.title && result.title.accessMode" [class]="'uk-label custom-label  label-'+ result.title.accessMode " title="Access Mode">{{result.title.accessMode}}</span>-->
186
<!--       <span *ngIf="result.funderShortname" class="uk-label custom-label label-funder " title="Funder">{{result.funderShortname}}</span>-->
187
<!--       <span *ngIf="result.title  && result.title.sc39" class="uk-label custom-label label-sc39 " title="Special Clause 39">Special Clause 39</span>-->
188

  
189
<!--       <div *ngIf="result.startYear && result.endYear"> Start year: {{result.startYear}} - End year: {{result.endYear}}</div>-->
190
<!--       <div *ngIf="result['organizations'] != undefined && result['organizations'].length > 0">-->
191
<!--           <span> Organization: </span>-->
192
<!--           <span *ngFor="let organization of result['organizations'].slice(0,10) let i=index">-->
193
<!--               <a *ngIf="organization.id" target="_blank"-->
194
<!--                  [href]="properties.baseOpenaireLink+'/search/organization?organizationId='+organization.id">-->
195
<!--                    <span>{{organization.name}}</span>-->
196
<!--                    <span class="custom-external custom-icon space"></span>-->
197
<!--               </a>-->
198
<!--             <span-->
199
<!--                   *ngIf="!organization.id">-->
200
<!--                       {{organization.name}}</span><span-->
201

  
202
<!--                   *ngIf="(i < result['organizations'].length-1) && (i < 9)">,</span>-->
203
<!--           </span>-->
204
<!--           <span *ngIf="result['organizations'].length > 10">...</span>-->
205
<!--       </div>-->
206
<!--   </li>-->
207
<!--</ul>-->
208

  
209
<div [class]="openaireSearchUtils.page > pagingLimit ? 'search-results' : ''" *ngIf="(openaireSearchUtils.page >= pagingLimit) && (openaireSearchUtils.totalResults > resultsPerPage*pagingLimit)">
210
    <p class="uk-alert-warning" uk-alert>For more results please try a new, more specific query</p>
211
</div>
212

  
213
<div *ngIf="openaireSearchUtils.totalResults > 0" class="uk-align-center uk-margin-remove-bottom">
214
  <div class="searchPaging uk-panel uk-margin-top uk-grid uk-margin-bottom">
215
    <span class="uk-h6 uk-width-1-1@s uk-width-1-2@m">
216
      {{openaireSearchUtils.totalResults | number}} projects, page {{openaireSearchUtils.page | number}} of {{(totalPages()) | number}}
217
    </span>
218
    <span class="float-children-right-at-medium margin-small-top-at-small uk-width-1-1@s uk-width-1-2@m">
219
      <paging-no-load [limitPaging]=true [currentPage]="openaireSearchUtils.page" [totalResults]="openaireSearchUtils.totalResults" [size]="rowsOnPage" (pageChange)="goTo($event.value)"></paging-no-load>
220
    </span>
221
  </div>
222
</div>
223
</div>
224
<!--  </div>-->
225
<!--</div>-->
modules/uoa-admin-portal/branches/new-UI/src/app/pages/projects/add-projects.component.ts
1
import { Component, ViewChild, OnInit, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core';
2
import { ActivatedRoute, Router } from "@angular/router";
3
//import { Subject } from 'rxjs/Subject';
4
import {SearchResult}     from '../../openaireLibrary/utils/entities/searchResult';
5
import {ErrorCodes} from '../../openaireLibrary/utils/properties/errorCodes';
6
import {SearchFields, FieldDetails} from '../../openaireLibrary/utils/properties/searchFields';
7
import {SearchUtilsClass } from '../../openaireLibrary/searchPages/searchUtils/searchUtils.class';
8
import {EnvProperties} from '../../openaireLibrary/utils/properties/env-properties';
9
import {SearchProjectsService} from '../../openaireLibrary/services/searchProjects.service';
10
import {RouterHelper} from '../../openaireLibrary/utils/routerHelper.class';
11
import {DOI, StringUtils} from '../../openaireLibrary/utils/string-utils.class';
12
import {ManageCommunityProjectsService} from '../../services/manageProjects.service';
13

  
14
import {Session} from '../../openaireLibrary/login/utils/helper.class';
15
import {LoginErrorCodes} from '../../openaireLibrary/login/utils/guardHelper.class';
16
import {properties} from "../../../environments/environment";
17
import {Subscriber} from "rxjs";
18
import {CommunityService} from "../../openaireLibrary/connect/community/community.service";
19
import {FormArray, FormBuilder, FormGroup} from "@angular/forms";
20
import {Option} from "../../openaireLibrary/sharedComponents/input/input.component";
21
import {debounceTime, distinctUntilChanged} from "rxjs/operators";
22
import {ResultPreview} from "../../openaireLibrary/utils/result-preview/result-preview";
23
import {SearchInputComponent} from "../../openaireLibrary/sharedComponents/search-input/search-input.component";
24

  
25
declare var UIkit;
26

  
27
@Component({
28
    selector: 'add-projects',
29
    templateUrl: './add-projects.component.html',
30
})
31

  
32
export class AddProjectsComponent implements OnInit {
33
  private subscriptions: any[] = [];
34
  @Output() communityProjectsChanged  = new EventEmitter();
35

  
36
  @Input() communityProjects = [];
37
  //@Output() communityProjectsChanged  = new EventEmitter();
38

  
39
  private community: string = '';
40

  
41
  public openaireProjects = [];
42
  public undo = {};
43
  public queryParameters: string = "";
44

  
45
  public funders:string[];
46
  public selectedFunderId:string = "";
47
  selectedFunderName:string ="Select funder:";
48

  
49
  public disableForms: boolean = false;
50

  
51
  public warningMessage = "";
52
  public infoMessage = "";
53

  
54
  public rowsOnPage:number  = 10;
55

  
56
  public routerHelper:RouterHelper = new RouterHelper();
57
  public errorCodes: ErrorCodes;
58
  public openaireSearchUtils:SearchUtilsClass = new SearchUtilsClass();
59
  public properties:EnvProperties = null;
60
  public pagingLimit:number = 0;
61
  public resultsPerPage: number = 0;
62

  
63
  public subFunders: any; public subResults: any; subAdd: any; subRemove: any;
64
  public body:string = "Send from page";
65

  
66
  @Output() toggleView: EventEmitter<any> = new EventEmitter();
67

  
68
  filterForm: FormGroup;
69
  // public fundersCtrl: FormArray;
70
  allOptions: Option[] = [];
71
  @ViewChild('searchInputComponent') searchInputComponent: SearchInputComponent;
72

  
73
  ngOnInit() {
74

  
75
     this.properties = properties;
76
     this.pagingLimit = properties.pagingLimit;
77
     this.resultsPerPage = properties.resultsPerPage;
78

  
79
    this.subscriptions.push(this.route.params.subscribe(params => {
80
       this.openaireSearchUtils.status = this.errorCodes.LOADING;
81

  
82
      // this.route.queryParams.subscribe(params => {
83
       this.community = params['community'];
84

  
85
       // this.community = params['communityId'];
86
       this.getFunders();
87
       this._getOpenaireProjects("", 1, 10);
88

  
89
       var referrer = null;
90
       if (typeof location !== 'undefined') {
91
         referrer = location.href;
92
       }
93
       this.body = "[Please write your message here]";
94
       this.body = StringUtils.URIEncode(this.body);
95
     }, error => {
96
      // this.openaireSearchUtils.status = this.errorCodes.
97
     }));
98

  
99
    this.openaireSearchUtils.keyword = "";
100

  
101
    // this.fundersCtrl = this._fb.array([]);
102
    this.filterForm = this._fb.group({
103
      keyword: [''],
104
      funder: []//this.fundersCtrl,
105
    });
106

  
107
    this.subscriptions.push(this.filterForm.get('keyword').valueChanges
108
      .pipe(debounceTime(1000), distinctUntilChanged())
109
      .subscribe(value => {
110
        this.keywordChanged(value);
111
      // this.applyFilters();
112
    }));
113

  
114
    this.subscriptions.push(this.filterForm.get('funder').valueChanges
115
      .pipe(debounceTime(1000), distinctUntilChanged())
116
      .subscribe(funderName => {
117
        console.log("funderName: "+funderName +" - selectedFunderId: "+this.selectedFunderId);
118

  
119
        if(funderName || this.selectedFunderId) {
120
          console.log("will be called funder changed: name="+funderName+", id="+this.getFunderIdByName(funderName));
121
          this.funderChanged(this.getFunderIdByName(funderName), funderName);
122
        }
123

  
124
      // this.page = 1;
125
      // this.applyFilters();
126
      //   if(value && value.id != undefined && value.id != this.selectedFunderId) {
127
      //     // if(value && value.id) {
128
      //     this.funderChanged(value.id, value.label);
129
      //     // }
130
      //   }
131
    }));
132
  }
133

  
134
  constructor(private route: ActivatedRoute, private _router: Router, private _searchProjectsService: SearchProjectsService,
135
              private _manageCommunityProjectsService: ManageCommunityProjectsService,
136
              private communityService: CommunityService, private _fb: FormBuilder) {
137
    this.errorCodes = new ErrorCodes();
138
    this.openaireSearchUtils.status = this.errorCodes.LOADING;
139
  }
140

  
141
  public ngOnDestroy() {
142
    this.subscriptions.forEach(sub => {
143
      if (sub instanceof Subscriber) {
144
        sub.unsubscribe();
145
      }
146
    });
147

  
148
    if(this.subFunders){
149
      this.subFunders.unsubscribe();
150
    }
151
    if(this.subResults){
152
      this.subResults.unsubscribe();
153
    }
154
    if(this.subAdd) {
155
      this.subAdd.unsubscribe();
156
    }
157
    if(this.subRemove) {
158
      this.subRemove.unsubscribe();
159
    }
160
  }
161

  
162
  public addProject(project: SearchResult) {
163
    if(!Session.isLoggedIn()){
164
      this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
165
    } else {
166
      this.subAdd = this._manageCommunityProjectsService.addProject(this.properties, this.community, project).subscribe(
167
        data => {
168
          this.undo[project.id] = data.id;
169
          this.communityProjects.push(data);
170
          UIkit.notification('Project successfully added!', {
171
            status: 'success',
172
            timeout: 6000,
173
            pos: 'bottom-right'
174
          });
175
          this.communityProjectsChanged.emit({
176
            value: this.communityProjects,
177
          });
178
        },
179
        err => {
180
          this.handleError('An error has been occurred. Try again later!');
181
          console.error(err.status);
182
        }/*,
183
        () => {
184
          console.info("completed ADD");
185
        }*/
186
      );
187
    }
188
  }
189

  
190
  public removeProject(project: any) {
191
    if(!Session.isLoggedIn()){
192
      this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
193
    } else {
194
      let projectId: string = this.getCommunityProjectId(project);
195
      this.subRemove = this._manageCommunityProjectsService.removeProject(this.properties, this.community, projectId).subscribe(
196
        data => {
197
          let index = this.communityProjects.indexOf(projectId);
198
          this.communityProjects.splice(index, 1);
199
          UIkit.notification('Project successfully removed!', {
200
            status: 'success',
201
            timeout: 6000,
202
            pos: 'bottom-right'
203
          });
204
          this.communityProjectsChanged.emit({
205
            value: this.communityProjects,
206
          });
207
        },
208
        err => {
209
          this.handleError('An error has been occurred. Try again later!');
210
          console.error(err);
211
        },
212
        () => {
213
          //this.undo[communityProjectId] = "";
214
        }
215
      )
216
    }
217
  }
218

  
219
  public getCommunityProjectId(project: any) : string {
220
    let index: number = 0;
221
    for(let communityProject of this.communityProjects) {
222
      if(communityProject.openaireId == project.id ||
223
          (project.code == communityProject.grantId && project.funderShortname == communityProject.funder)) {
224
        return communityProject.id;
225
      }
226
      index++;
227
    }
228
    return "";
229
  }
230

  
231
  //public inCommunity(project: any): any {
232
    // for(let communityProject of this.communityProjects) {
233
    //   if(communityProject.openaireId == project.id) {
234
    //     return true;
235
    //   } else if(project.code == communityProject.grantId && project.funderShortname == communityProject.funder) {
236
    //     return true;
237
    //   }
238
    // }
239
    //
240
    // // if(this.undo[project.id]) {
241
    // //   return true;
242
    // // }
243
    // return false;
244

  
245
    //return this.getCommunityProjectId(project);
246
  //}
247

  
248
  getFunderNames(): string[] {
249
    return this.funders.map(funder => {
250
      return funder['name'];
251
    })
252
  }
253

  
254
  getFunderIdByName(funderName: string): string {
255
    if(funderName == "") {
256
      return "";
257
    }
258
    for(let funder of this.funders) {
259
      if(funder['name'] == funderName) {
260
        return funder['id'];
261
      }
262
    }
263
    return funderName;
264
  }
265

  
266
  getFunders ()  {
267
    if(!Session.isLoggedIn()){
268
      this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
269
    } else {
270
      this.subFunders = this._searchProjectsService.getFunders(this.properties).subscribe(
271
        data => {
272
          this.funders = data[1];
273
          console.log("funders: ",this.funders);
274
          this.allOptions = [];
275
          let i;
276
          this.allOptions.push({label: 'Select funder:', value: {id: '', label: 'Select funder:'}});
277
          for(i=0; i<this.funders.length; i++) {
278
            let funder = this.funders[i];
279
            if(funder && funder['id']) {
280
              this.allOptions.push({label: funder['name'], value: {id:funder['id'], label: funder['name']}});
281
            }
282
          }
283
        },
284
        err => console.error(err)
285
      );
286
    }
287
  }
288

  
289
  public getResultPreview(result: SearchResult): ResultPreview {
290
    return ResultPreview.searchResultConvert(result, "project");
291
  }
292

  
293
  private _getOpenaireProjects(parameters:string, page: number, size: number){
294
    if(!Session.isLoggedIn()){
295
      this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
296
    } else {
297
      if(page > this.pagingLimit) {
298
        size=0;
299
      }
300

  
301
      if(this.openaireSearchUtils.status == this.errorCodes.LOADING) {
302
        this.openaireSearchUtils.status = this.errorCodes.LOADING;
303

  
304
        this.disableForms = true;
305
        this.openaireProjects = [];
306
        this.openaireSearchUtils.totalResults = 0;
307

  
308
        this.subResults = this._searchProjectsService.searchProjects(parameters, null, page, size, [], this.properties).subscribe(
309
          data => {
310
              this.undo = {};
311
              this.openaireSearchUtils.totalResults = data[0];
312
              this.openaireProjects = data[1];
313

  
314
              //this.searchPage.checkSelectedFilters(this.filters);
315
              this.openaireSearchUtils.status = this.errorCodes.DONE;
316
              if(this.openaireSearchUtils.totalResults == 0 ){
317
                this.openaireSearchUtils.status = this.errorCodes.NONE;
318
              }
319

  
320
              this.disableForms = false;
321

  
322
              if(this.openaireSearchUtils.status == this.errorCodes.DONE) {
323
                // Page out of limit!!!
324
                let totalPages:any = this.openaireSearchUtils.totalResults/(this.openaireSearchUtils.size);
325
                if(!(Number.isInteger(totalPages))) {
326
                    totalPages = (parseInt(totalPages, 10) + 1);
327
                }
328
                if(totalPages < page) {
329
                  this.openaireSearchUtils.totalResults = 0;
330
                  this.openaireSearchUtils.status = this.errorCodes.OUT_OF_BOUND;
331
                }
332
              }
333
          },
334
          err => {
335
              console.error(err);
336
               //TODO check erros (service not available, bad request)
337
              if(err.status == '404') {
338
                this.openaireSearchUtils.status = this.errorCodes.NOT_FOUND;
339
              } else if(err.status == '500') {
340
                this.openaireSearchUtils.status = this.errorCodes.ERROR;
341
              } else {
342
                this.openaireSearchUtils.status = this.errorCodes.NOT_AVAILABLE;
343
              }
344

  
345
              this.disableForms = false;
346
          }
347
        );
348
      }
349
    }
350
  }
351

  
352
  totalPages(): number {
353
    let totalPages:any = this.openaireSearchUtils.totalResults/(this.rowsOnPage);
354
    if(!(Number.isInteger(totalPages))) {
355
        totalPages = (parseInt(totalPages, 10) + 1);
356
    }
357
    return totalPages;
358
  }
359

  
360
  keywordChanged(keyword) {
361
    this.openaireSearchUtils.keyword = keyword;
362
    this.buildQueryParameters();
363
    this.goTo(1);
364
  }
365

  
366
  funderChanged(funderId:string, funderName:string){
367
    this.selectedFunderId = funderId;
368
    this.selectedFunderName = funderName;
369

  
370
    this.buildQueryParameters();
371
    this.goTo(1);
372
  }
373

  
374
  buildQueryParameters() {
375
    this.queryParameters = "";
376

  
377
    if(this.openaireSearchUtils.keyword) {
378
      this.queryParameters = "q="+StringUtils.URIEncode(this.openaireSearchUtils.keyword);
379
    }
380

  
381
    if(this.selectedFunderId) {
382
      this.queryParameters += this.queryParameters ? "&" : "";
383
      this.queryParameters += "fq=funder exact " + '"'+StringUtils.URIEncode(this.selectedFunderId)+ '"';
384
    }
385
  }
386

  
387
  // buildQueryParameters() {
388
  //   this.queryParameters = "";
389
  //
390
  //   if(this.openaireSearchUtils.keyword) {
391
  //     this.queryParameters = "q="+StringUtils.URIEncode(this.openaireSearchUtils.keyword);
392
  //   }
393
  //
394
  //   if(this.fundersCtrl.getRawValue().length > 0) {
395
  //     this.queryParameters += this.queryParameters ? "&" : "";
396
  //   }
397
  //
398
  //   for (let funder of this.fundersCtrl.getRawValue()) {
399
  //     //if(this.selectedFunderId != "0") {
400
  //     this.queryParameters += "fq=funder exact " + '"'+StringUtils.URIEncode(this.selectedFunderId)+ '"';
401
  //   }
402
  // }
403

  
404
  goTo(page:number = 1){
405
    this.openaireSearchUtils.page=page;
406
    this.openaireSearchUtils.status = this.errorCodes.LOADING;
407
    this._getOpenaireProjects(this.queryParameters, page, 10);
408
  }
409

  
410
  back() {
411
    this.toggleView.emit(null);
412
  }
413

  
414
  public onSearchClose() {
415
    this.openaireSearchUtils.keyword = this.filterForm.get('keyword').value;
416
  }
417

  
418
  public resetInput() {
419
    this.openaireSearchUtils.keyword = null;
420
    this.searchInputComponent.reset()
421
  }
422

  
423
  handleError(message: string) {
424
    UIkit.notification(message, {
425
      status: 'danger',
426
      timeout: 6000,
427
      pos: 'bottom-right'
428
    });
429
  }
430
}
modules/uoa-admin-portal/branches/new-UI/src/app/pages/projects/manage-projects.component.ts
1
import { Component, ViewChild, OnInit, Input, ElementRef } from '@angular/core';
2
import { ActivatedRoute, Router } from "@angular/router";
3

  
4
import {RemoveProjectsComponent} from './remove-projects.component';
5
import {AddProjectsComponent} from './add-projects.component';
6

  
7
import {Session} from '../../openaireLibrary/login/utils/helper.class';
8
import {LoginErrorCodes} from '../../openaireLibrary/login/utils/guardHelper.class';
9
import {HelperFunctions} from "../../openaireLibrary/utils/HelperFunctions.class";
10
import {Title} from '@angular/platform-browser';
11
import {CommunityService} from "../../openaireLibrary/connect/community/community.service";
12
import {FullScreenModalComponent} from "../../openaireLibrary/utils/modal/full-screen-modal/full-screen-modal.component";
13
import {StringUtils} from "../../openaireLibrary/utils/string-utils.class";
14
import {EnvProperties} from "../../openaireLibrary/utils/properties/env-properties";
15
import {properties} from "../../../environments/environment";
16

  
17
@Component({
18
  selector: 'manage-projects',
19
  template: `    
20
      <remove-projects (toggleView)="toggleAction()" [communityProjects]="communityProjects" [showLoading]="showLoadingInRemove"
21
                       (communityProjectsChanged)="communityProjectsChanged($event)" [toggle]="toggle">
22
      </remove-projects>
23
      <fs-modal #fsModal (cancelEmitter)="toggleAction()">
24
        <div actions class="uk-flex uk-flex-middle uk-height-1-1">
25
          <div class=" uk-text-secondary">
26
            <icon class="uk-button" name="info" ratio="1.5"></icon>
27
          </div>
28
          <div *ngIf="community" uk-drop="mode: hover">
29
            <div class="uk-card uk-card-body uk-card-default">
30
              If you cannot find a funder that is relevant for your community, please contact us 
31
              (<a [href]="'mailto:' + properties.feedbackmailForMissingEntities +'?Subject=[OpenAIRE Connect - '+ community + '] report missing Funder' + '&body=' + body" target="_top">{{properties.feedbackmailForMissingEntities}}</a>) 
32
              and we will try to get the funder on board!
33
            </div>
34
          </div>
35
        </div>
36

  
37
<!--        *ngIf="alreadyToggled"-->
38
        <add-projects [communityProjects]="communityProjects" (communityProjectsChanged)="communityProjectsChanged($event)"></add-projects>
39
      </fs-modal>
40
  `
41
})
42

  
43
export class ManageProjectsComponent implements OnInit {
44
  @Input() communityProjects =[];
45
  @ViewChild (RemoveProjectsComponent) removeProjectsComponent : RemoveProjectsComponent ;
46
  @ViewChild (AddProjectsComponent) addProjectsComponent : AddProjectsComponent ;
47
  @ViewChild('fsModal') fullscreen:FullScreenModalComponent;
48

  
49
  public pageTitle: string = "Manage community projects";
50
  public toggle: boolean = false;
51
  // public alreadyToggled: boolean = false;
52
  public updateCommunityProjectsOnToggle: boolean = false;
53

  
54
  private subscriptions: any[] = [];
55

  
56
  public showLoadingInRemove: boolean = true;
57

  
58
  public body:string = "Send from page";
59
  public properties: EnvProperties = properties;
60
  public community: string = "";
61

  
62
  ngAfterViewInit() {
63
    // this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(community => {
64
    //   if(community) {
65
    //     this.community = community.communityId;
66
    //     this.title.setTitle('Administration Dashboard | Projects');
67
    //     this.body = "[Please write your message here]";
68
    //     this.body = StringUtils.URIEncode(this.body);
69
    //
70
    //     if(this.removeProjectsComponent) {
71
    //       // this.removeProjectsComponent._getCommunityProjects();
72
    //     }
73
    //   }
74
    // }));
75
  }
76

  
77
  ngOnInit() {
78
    this.subscriptions.push(this.route.params.subscribe(params => {
79
      let communityId = params['community'];
80

  
81
      if(communityId) {
82
        this.title.setTitle(communityId.toUpperCase() + ' | Projects');
83
        this.body = "[Please write your message here]";
84
        this.body = StringUtils.URIEncode(this.body);
85
      }
86
    }));
87

  
88
    this.fullscreen.title = "Search and Add Projects";
89
    this.fullscreen.okButtonText = "Done";
90
    this.fullscreen.okButton = true;
91
  }
92

  
93
  constructor(private element: ElementRef,
94
              private title: Title,
95
              private route: ActivatedRoute, private _router: Router,
96
              private communityService: CommunityService) {}
97

  
98
  public ngOnDestroy() {}
99

  
100
  // public updateCommunityProjects() {
101
  //   if(!Session.isLoggedIn()){
102
  //     this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
103
  //   } else {
104
  //     HelperFunctions.scroll();
105
  //
106
  //     this.toggle = !this.toggle;
107
  //     if(this.toggle) {
108
  //
109
  //       //if(this.updateCommunityProjectsOnToggle) {
110
  //         this.removeProjectsComponent._getCommunityProjects();
111
  //         this.addProjectsComponent.undo = {};
112
  //       //}
113
  //     } else {
114
  //       this.updateCommunityProjectsOnToggle = false;
115
  //     }
116
  //   }
117
  // }
118

  
119
  public toggleAction() {
120
    // this.alreadyToggled = true;
121
    if (!Session.isLoggedIn()) {
122
      this._router.navigate(['/user-info'], {
123
        queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl':  this._router.url} });
124
    } else {
125
      HelperFunctions.scroll();
126

  
127
      this.toggle = !this.toggle;
128
      if (this.toggle) {
129
        this.fullscreen.open();
130
        this.pageTitle = 'Search community projects';
131
      } else {
132
        // this.updateCommunityProjectsOnToggle = false;
133
        this.pageTitle = 'Manage community projects';
134
      }
135
    }
136
  }
137

  
138
  public communityProjectsChanged($event) {
139
    this.communityProjects = $event.value;
140
    this.showLoadingInRemove = false;
141

  
142
    if(this.toggle) {
143
      this.removeProjectsComponent.applyFilters();
144
      this.removeProjectsComponent.createFunderFilter();
145
    }
146
  }
147

  
148
  // public updateCommunityProjects($event) {
149
  //   this.updateCommunityProjectsOnToggle = true;
150
  // }
151
}
modules/uoa-admin-portal/branches/new-UI/src/app/pages/projects/communityProjects.module.ts
1
import { NgModule } from '@angular/core';
2
import { HttpClientModule } from '@angular/common/http';
3
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4
import { RouterModule } from '@angular/router';
5

  
6

  
7
import { EnvironmentSpecificResolver } from '../../openaireLibrary/utils/properties/environmentSpecificResolver';
8
import { EnvironmentSpecificService } from '../../openaireLibrary/utils/properties/environment-specific.service';
9

  
10
import { DataTablesModule } from 'angular-datatables';
11
import { ManageProjectsComponent } from './manage-projects.component';
12
import { ManageCommunityProjectsService } from '../../services/manageProjects.service';
13
import { SearchProjectsServiceModule } from '../../openaireLibrary/connect/projects/searchProjectsService.module';
14

  
15
import { RemoveProjectsComponent } from './remove-projects.component';
16
import { AddProjectsComponent } from './add-projects.component';
17
import { SearchProjectsService } from '../../openaireLibrary/services/searchProjects.service';
18
import { PagingModule } from '../../openaireLibrary/utils/paging.module';
19
import { SearchPagingModule } from '../../openaireLibrary/searchPages/searchUtils/searchPaging.module';
20

  
21
import {ErrorMessagesModule} from '../../openaireLibrary/utils/errorMessages.module';
22
import {AlertModalModule} from '../../openaireLibrary/utils/modal/alertModal.module';
23
import {FABModule} from '../../utils/fabModule.module';
24
import {CommonModule} from '@angular/common';
25
import {PageContentModule} from "../../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
26
import {CommunityInfoModule} from "../community-info/community-info.module";
27
import {InputModule} from "../../openaireLibrary/sharedComponents/input/input.module";
28
import {SearchInputModule} from "../../openaireLibrary/sharedComponents/search-input/search-input.module";
29
import {NoLoadPaging} from "../../openaireLibrary/searchPages/searchUtils/no-load-paging.module";
30
import {LoadingModule} from "../../openaireLibrary/utils/loading/loading.module";
31
import {IconsModule} from "../../openaireLibrary/utils/icons/icons.module";
32
import {IconsService} from "../../openaireLibrary/utils/icons/icons.service";
33
import {add, arrow_left, close, remove_circle_outline, info} from "../../openaireLibrary/utils/icons/icons";
34
import {FullScreenModalModule} from "../../openaireLibrary/utils/modal/full-screen-modal/full-screen-modal.module";
35
import {ResultPreviewModule} from "../../openaireLibrary/utils/result-preview/result-preview.module";
36

  
37
@NgModule({
38
  imports: [
39
    CommonModule,
40
    HttpClientModule,
41
    FormsModule,
42
    ReactiveFormsModule,
43
    RouterModule,
44
    DataTablesModule,
45
    PagingModule, SearchPagingModule,
46
    ErrorMessagesModule,
47
    AlertModalModule,
48
    SearchProjectsServiceModule,
49
    FABModule,
50
    PageContentModule,
51
    CommunityInfoModule,
52
    InputModule,
53
    SearchInputModule,
54
    RouterModule.forChild([
55
      {
56
        path: '', component: ManageProjectsComponent
57
      }
58
    ]),
59
    NoLoadPaging, LoadingModule, IconsModule, FullScreenModalModule, ResultPreviewModule
60
  ],
61
    declarations: [
62
        ManageProjectsComponent,
63
        RemoveProjectsComponent,
64
        AddProjectsComponent
65
    ],
66
    providers: [
67
        ManageCommunityProjectsService,
68
        SearchProjectsService,
69
        EnvironmentSpecificResolver, EnvironmentSpecificService
70
    ],
71
    exports: [ManageProjectsComponent]
72
})
73

  
74
export class CommunityProjectsModule {
75
  constructor(private iconsService: IconsService) {
76
    this.iconsService.registerIcons([remove_circle_outline, add, close, arrow_left, info]);
77
  }
78
}
modules/uoa-admin-portal/branches/new-UI/src/app/pages/projects/remove-projects.component.html
1
<div page-content>
2
  <div header>
3
    <community-info tab="projects"></community-info>
4
    <div [class.uk-invisible]="showLoading" class="uk-width-1-1 uk-flex uk-flex-right@m uk-flex-center uk-flex-wrap uk-flex-middle uk-grid" uk-grid>
5
      <div #searchInputComponent search-input [control]="filterForm.controls.keyword" [showSearch]="false" placeholder="Search"
6
           [selected]="communitySearchUtils.keyword" (closeEmitter)="onSearchClose()" (resetEmitter)="resetInput()"
7
           [bordered]="true" colorClass="uk-text-secondary" toggleTitle="locate projects"
8
           class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1"></div>
9
      <div>
10
        <a class="uk-text-uppercase uk-flex uk-flex-middle" (click)="addNew()"
11
           [attr.uk-tooltip]="(toggle? 'cls: uk-invisible; ' : 'cls: uk-active; ') +
12
                'title: <div class=\'uk-padding-small\'><div class=\'uk-margin-bottom uk-text-bold\'> Search and add more Projects</div><div>The research results linked to the projects specified here will be automatically linked to your community dashboard.</div></div>'">
13
          <button class="uk-icon-button large uk-button-secondary">
14
            <icon name="add"></icon>
15
          </button>
16
          <button class="uk-button uk-button-link uk-margin-small-left uk-text-secondary">Add new project</button>
17
        </a>
18
      </div>
19
    </div>
20
  </div>
21
  <div inner>
22
    <div *ngIf="showLoading" class="uk-margin-large-top">
23
      <loading></loading>
24
    </div>
25

  
26
    <div *ngIf="!showLoading">
27
      <div>
28
        <div class="uk-grid uk-flex uk-flex-middle uk-margin-medium-bottom" uk-grid>
29
          <div *ngIf="allOptions.length > 0"
30
               class="uk-grid uk-flex-middle uk-flex-left@m uk-flex-center uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1 uk-first-column">
31
            <span class="">Filter by: </span>
32
<!--            uk-width-expand@m uk-width-auto-->
33
            <div class="uk-width-expand uk-padding-remove uk-margin-small-left" dashboard-input
34
                 [formInput]="filterForm.get('funder')"
35
                 placeholder="Search by funders"
36
                 type="chips" [options]="allOptions"   chipLabel="label">
37
            </div>
38
          </div>
39
          <div *ngIf="previewCommunityProjects.length > 0"
40
               class="uk-width-expand@m uk-width-1-1">
41
            <div class="uk-flex-middle uk-flex-right@m uk-flex-center uk-grid">
42
              <span class="">Sort by: </span>
43
              <div  class="uk-width-medium uk-padding-remove uk-margin-small-left"  dashboard-input
44
                    [formInput]="filterForm.get('sort')"
45
                    type="select"
46
                    [options]="sortOptions">
47
              </div>
48
            </div>
49
          </div>
50
        </div>
51
        <no-load-paging *ngIf="previewCommunityProjects.length > 0" [type]="'projects'"
52
                        (pageChange)="updatePage($event)"
53
                        [page]="page" [pageSize]="pageSize"
54
                        [totalResults]="previewCommunityProjects.length">
55
        </no-load-paging>
56
        <div class="uk-margin-medium-top uk-margin-medium-bottom">
57
          <div *ngIf="previewCommunityProjects.length == 0"
58
               class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
59
            <div>No projects for {{name}}</div>
60
          </div>
61
          <div class="uk-card uk-card-default uk-card-body uk-text-small uk-margin-bottom"
62
               *ngFor="let item of previewCommunityProjects.slice((page - 1)*pageSize, page*pageSize)">
63
            <div class="uk-grid uk-grid-divider uk-flex uk-flex-middle" uk-grid>
64
              <div class="uk-width-expand@m uk-width-1-1">
65
                <div class="uk-padding-small uk-padding-remove-horizontal">
66
                  <h6 *ngIf="item.name || item.acronym || item.openaireId || item.grantId || item.funder"
67
                       class="uk-margin-small-bottom">
68
                    <a *ngIf="item.openaireId || item.grantId || item.funder"
69
                       target="_blank"
70
                       [href]="communityUrl+'/search/project?' + ((item.openaireId) ? 'projectId='+item.openaireId : 'grantId='+item.grantId+'&funder='+item.funder)">
71
                      <span *ngIf="item.name">{{item.name}}</span>
72
                      <span *ngIf="item.name && item.acronym">(</span><span *ngIf="item.acronym">{{item.acronym}}</span><span *ngIf="item.name && item.acronym">)</span>
73
                      <span *ngIf="!item.name && !item.acronym">[no title available]</span>
74
                      <span class="custom-external custom-icon space"></span>
75
                    </a>
76
                    <span *ngIf="!item.openaireId && !item.grantId && !item.funder">
77
                      <span *ngIf="item.name">{{item.name}}</span>
78
                      <span *ngIf="item.name && item.acronym">(</span><span *ngIf="item.acronym">{{item.acronym}}</span><span *ngIf="item.name && item.acronym">)</span>
79
                      <span *ngIf="!item.name && !item.acronym">[no title available]</span>
80
                    </span>
81
                  </h6>
82
                  <div *ngIf="item.grantId" class="uk-margin-small-bottom">
83
                    <span class="title">Grant ID: </span>
84
                    <span>{{item.grantId}}</span>
85
                  </div>
86
                  <div *ngIf="item.funder" class="uk-margin-small-bottom">
87
                    <span class="title">Funder: </span>
88
                    <span>{{item.funder}}</span>
89
                  </div>
90
                </div>
91
              </div>
92
              <div class="uk-width-auto@m uk-width-1-1">
93
                <div class="uk-padding-small uk-padding-remove-horizontal uk-flex uk-flex-center">
94
                  <a (click)="removeProject(item)" class="uk-button action uk-flex uk-flex-middle">
95
                    <icon name="remove_circle_outline" ratio="0.7"></icon>
96
                    <span class="uk-margin-small-left">Remove project</span>
97
                  </a>
98
                </div>
99
              </div>
100
            </div>
101
          </div>
102
        </div>
103
        <no-load-paging *ngIf="previewCommunityProjects.length > 0" [type]="'projects'"
104
                        (pageChange)="updatePage($event)"
105
                        [page]="page" [pageSize]="pageSize"
106
                        [totalResults]="previewCommunityProjects.length">
107
        </no-load-paging>
108
      </div>
109
    </div>
110

  
111

  
112
<!--  <div class="uk-child-width-expand@s uk-text-center uk-margin-bottom" uk-grid>-->
113
<!--    <div>-->
114
<!--      <form class=" uk-animation uk-card uk-card-default uk-padding" >-->
115
<!--        <div>-->
116
<!--          <select class="uk-select"  [(ngModel)]="selectedFunder" name="select_funder"  >-->
117
<!--           <option  value="" (click)="goTo(1)">Select funder:</option>-->
118
<!--           <option *ngFor="let  funder of funders"  [value]="funder" (click)="goTo(1)">{{funder}}</option>-->
119
<!--          </select>-->
120
<!--        </div>-->
121
<!--      </form>-->
122
<!--    </div>-->
123
<!--    <div>-->
124
<!--      <form class="uk-text-center uk-animation uk-card uk-card-default uk-padding">-->
125
<!--        <div>-->
126
<!--          <input type="text" class="uk-input  uk-width-1-2" placeholder="Search community projects..." aria-describedby="sizing-addon2"  [(ngModel)]="communitySearchUtils.keyword"  name="keyword" >-->
127
<!--          <button (click)="goTo(1)"  type="submit" class=" uk-button">-->
128
<!--             <span class="uk-icon">-->
129
<!--             <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="search" ratio="1"><circle fill="none" stroke="#000" stroke-width="1.1" cx="9" cy="9" r="7"></circle><path fill="none" stroke="#000" stroke-width="1.1" d="M14,14 L18,18 L14,14 Z"></path></svg>-->
130
<!--             </span>Search-->
131
<!--           </button>-->
132
<!--        </div>-->
133
<!--      </form>-->
134
<!--    </div>-->
135
<!--  </div>-->
136

  
137
<!--  <errorMessages [status]="[communitySearchUtils.status]" [type]="'community projects'"></errorMessages>-->
138
<!--  <div *ngIf="communitySearchUtils.status == errorCodes.DONE" class="uk-alert uk-alert-primary">-->
139
<!--    <span class="uk-margin-small-right uk-icon" uk-icon="warning"></span>-->
140
<!--  All the research results linked to the projects specified here will be automatically linked to your community dashboard.  -->
141
<!--  </div>-->
142
<!--  <div *ngIf="communitySearchUtils.totalResults > 0" class="uk-align-center uk-margin-remove-bottom">-->
143
<!--    <div class="searchPaging uk-panel uk-margin-top uk-grid uk-margin-bottom">-->
144
<!--      <span class="uk-h6 uk-width-1-1@s uk-width-1-2@m">-->
145
<!--        {{communitySearchUtils.totalResults | number}} projects, page {{communitySearchUtils.page | number}} of {{(totalPages()) | number}}-->
146
<!--      </span>-->
147
<!--      <span class="float-children-right-at-medium margin-small-top-at-small uk-width-1-1@s uk-width-1-2@m">-->
148
<!--        <paging-no-load [currentPage]="communitySearchUtils.page" [totalResults]="communitySearchUtils.totalResults" [size]="10" (pageChange)="goTo($event.value, false)"></paging-no-load>-->
149
<!--      </span>-->
150
<!--    </div>-->
151
<!--  </div>-->
152

  
153
<!--  <div *ngIf="communitySearchUtils.totalResults > 0" class="uk-align-center uk-margin-remove-bottom">-->
154
<!--    <div class="searchPaging uk-panel uk-margin-top uk-grid uk-margin-bottom">-->
155
<!--      <span class="uk-h6 uk-width-1-1@s uk-width-1-2@m">-->
156
<!--        {{communitySearchUtils.totalResults | number}} projects, page {{communitySearchUtils.page | number}} of {{(totalPages()) | number}}-->
157
<!--      </span>-->
158
<!--      <span class="float-children-right-at-medium margin-small-top-at-small uk-width-1-1@s uk-width-1-2@m">-->
159
<!--        <paging-no-load [currentPage]="communitySearchUtils.page" [totalResults]="communitySearchUtils.totalResults" [size]="10" (pageChange)="goTo($event.value, false)"></paging-no-load>-->
160
<!--      </span>-->
161
<!--    </div>-->
162
<!--  </div>-->
163

  
164
  <modal-alert #AlertModalDeleteCommunity (alertOutput)="confirmedDeleteProject($event)"></modal-alert>
165
  <!-- <delete-confirmation-dialog #deleteConfirmationModal [isModalShown]="isModalShown" (emmitObject)="confirmedDeleteProject($event)">
166
      Are you sure you want to remove the selected project from your community?
167
  </delete-confirmation-dialog> -->
168
<!-- </div> -->
169

  
170

  
171
  </div>
172
</div>
modules/uoa-admin-portal/branches/new-UI/src/app/pages/projects/remove-projects.component.ts
1
import { Component, ViewChild, OnInit, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core';
2
import { ActivatedRoute, Router } from "@angular/router";
3
import {Subject, Subscriber} from 'rxjs';
4
import { DataTableDirective } from 'angular-datatables';
5

  
6
import {ErrorCodes} from '../../openaireLibrary/utils/properties/errorCodes';
7
import {SearchUtilsClass } from '../../openaireLibrary/searchPages/searchUtils/searchUtils.class';
8
import {EnvProperties} from '../../openaireLibrary/utils/properties/env-properties';
9
import {ManageCommunityProjectsService} from '../../services/manageProjects.service';
10
import {SearchCommunityProjectsService} from '../../openaireLibrary/connect/projects/searchProjects.service';
11
import {RouterHelper} from '../../openaireLibrary/utils/routerHelper.class';
12
import {DOI, StringUtils} from '../../openaireLibrary/utils/string-utils.class';
13

  
14
import {Session} from '../../openaireLibrary/login/utils/helper.class';
15
import {LoginErrorCodes} from '../../openaireLibrary/login/utils/guardHelper.class';
16
import {FormArray, FormBuilder, FormGroup, Validators} from "@angular/forms";
17
import {ConnectHelper} from "../../openaireLibrary/connect/connectHelper";
18
import {properties} from "../../../environments/environment";
19
import {CommunityService} from "../../openaireLibrary/connect/community/community.service";
20
import {Option} from "../../openaireLibrary/sharedComponents/input/input.component";
21
import {CheckPortal, Portal} from "../../openaireLibrary/utils/entities/adminTool/portal";
22
import {SearchInputComponent} from "../../openaireLibrary/sharedComponents/search-input/search-input.component";
23

  
24
declare var UIkit;
25

  
26
@Component({
27
    selector: 'remove-projects',
28
    templateUrl: './remove-projects.component.html',
29
    // styles: [`
30
    //   #dpTable_info, #dpTable_paginate,  #dpTable_length,  #dpTable_filter{
31
    //     display: none;
32
    //   }
33
    // `],
34
    // encapsulation: ViewEncapsulation.None // this used in order styles to work
35
})
36

  
37
export class RemoveProjectsComponent implements OnInit {
38
  public routerHelper:RouterHelper = new RouterHelper();
39

  
40
  private community: string = '';
41
  private communityUrl = "https://beta.explore.openaire.eu";
42

  
43
  public errorCodes: ErrorCodes;
44

  
45
  @Output() communityProjectsChanged  = new EventEmitter();
46
  @Input() public communityProjects = [];
47
  public previewCommunityProjects = [];
48
  public communitySearchUtils:SearchUtilsClass = new SearchUtilsClass();
49

  
50
  public sub: any; public subResults: any; subRemove: any;
51
  properties:EnvProperties = properties;
52

  
53
  public disableForms: boolean = false;
54

  
55
  dtOptions: DataTables.Settings = {};
56
  showTable = false; filteringAdded = false;
57
  @ViewChild(DataTableDirective) datatableElement: DataTableDirective;
58
  dtTrigger: Subject<any> = new Subject(); //necessary
59

  
60
  public rowsOnPage:number  = 10;
61

  
62
  public queryParameters: string = "";
63

  
64
  public query = '';
65
  public selectedProjects=[] ;
66
  public elementRef;
67

  
68
  public funders:Set<string>;
69
  public selectedFunder:string ="";
70
  //@Output() projectSelected = new EventEmitter();
71
  //@Input() public properties:EnvProperties;
72

  
73
  public projects:string[];
74
  private triggered: boolean = false;
75

  
76
  private selectedCommunityProject: any;
77

  
78
  @ViewChild('AlertModalDeleteCommunity') alertModalDeleteCommunity;
79
  @ViewChild('searchInputComponent') searchInputComponent: SearchInputComponent;
80

  
81

  
82
  @Input() public showLoading: boolean = true;
83
  private subscriptions: any[] = [];
84
  /* Paging */
85
  page: number = 1;
86
  pageSize: number = 10;
87
  public portal: string;
88
  public name: string;
89
  public isPortalAdministrator = null;
90
  /* Search */
91
  filterForm: FormGroup;
92
  public fundersCtrl: FormArray;
93
  private searchText: RegExp = new RegExp('');
94
  public keyword: string = '';
95
  allOptions: Option[] = [];
96
  sortOptions: Option[] = [
97
    //{label:"Title (desc) ", value:{ sort: "title",descending: true }},
98
    {label:"Title ", value: { sort: "title",descending:false }},
99
    //{label:"Grant ID (desc) ", value:{ sort: "grant",descending: true }},
100
    {label:"Grant ID ", value: { sort: "grant",descending:false }},
101
    //{label:"Funder (desc) ", value:{ sort: "funder",descending: true }},
102
    {label:"Funder ", value: { sort: "funder",descending:false }}
103
  ];
104

  
105
  @Output() toggleView: EventEmitter<any> = new EventEmitter();
106
  @Input() public toggle: boolean = true;
107

  
108
  ngOnInit() {
109
    this.communitySearchUtils.keyword = "";
110

  
111
    this.fundersCtrl = this._fb.array([]);
112
    this.filterForm = this._fb.group({
113
      keyword: [''],
114
      funder: this.fundersCtrl,
115
      sort: this._fb.control(this.sortOptions[0].value)
116
    });
117

  
118
    this.subscriptions.push(this.filterForm.get('keyword').valueChanges.subscribe(value => {
119
      this.searchText = new RegExp(value, 'i');
120
      this.page = 1;
121
      this.applyFilters();
122
    }));
123

  
124
    this.subscriptions.push(this.filterForm.get('funder').valueChanges.subscribe(value => {
125
      console.log("funder changed: ",value);
126
      this.page = 1;
127
      this.applyFilters();
128
    }));
129

  
130
    this.subscriptions.push(this.filterForm.get('sort').valueChanges.subscribe(value => {
131
      this.page = 1;
132
      this.sort();
133
    }));
134

  
135
    this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(community => {
136
      if(community) {
137
        this.portal = community.communityId;
138
        this.name = community.shortTitle;
139
        this.communityUrl = "https://beta."+this.portal+".openaire.eu";
140

  
141
        this.keyword = '';
142
        this._getCommunityProjects();
143
        // this.initPreviewCommunityProjects();
144
      }
145
    }));
146
  }
147

  
148
  constructor(private route: ActivatedRoute, private _router: Router,
149
              private _fb: FormBuilder,
150
              private communityService: CommunityService,
151
              private _manageCommunityProjectsService: ManageCommunityProjectsService,
152
              private _searchCommunityProjectsService: SearchCommunityProjectsService) {
153
    this.errorCodes = new ErrorCodes();
154
    this.communitySearchUtils.status = this.errorCodes.LOADING;
155
  }
156

  
157
  public ngOnDestroy() {
158
    this.subscriptions.forEach(sub => {
159
      if (sub instanceof Subscriber) {
160
        sub.unsubscribe();
161
      }
162
    });
163
  }
164

  
165
  // changekeyword() {
166
  //   if (this.filterForm.get("keyword").value.length >= 3 || this.filterForm.get("keyword").value.length == 0) {
167
  //     this.searchTermStream.next(this.filterForm.get("keyword").value);
168
  //   }
169
  // }
170

  
171
  public inCommunity(result: any): any {
172
    let found = false;
173
    for(let project of this.communityProjects) {
174
      if(project.opeaireId == result.id) {
175
        return true;
176
      } else if(result['title'].name.search("("+project.grantId+")") != -1 && result.funderShortname == project.funder) {
177
        return true;
178
      }
179
    }
180
    return found;
181

  
182
  }
183

  
184
  totalPages(): number {
185
      let totalPages:any = this.communitySearchUtils.totalResults/(this.rowsOnPage);
186
      if(!(Number.isInteger(totalPages))) {
187
          totalPages = (parseInt(totalPages, 10) + 1);
188
      }
189
      return totalPages;
190
  }
191

  
192
  public confirmedDeleteProject(data : any) {
193
    if(!Session.isLoggedIn()){
194
      this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
195
    } else {
196
      this.subscriptions.push(this._manageCommunityProjectsService.removeProject(this.properties, this.portal, this.selectedCommunityProject.id).subscribe(
197
        data => {
198
          let index = this.communityProjects.indexOf(this.selectedCommunityProject);
199
          this.communityProjects.splice(index, 1);
200

  
201
          this.applyFilters();
202

  
203
          // index = this.previewCommunityProjects.indexOf(this.selectedCommunityProject);
204
          // this.previewCommunityProjects.splice(index, 1);
205
          //
206
          // console.log("after previewCommunityProjects: ",this.previewCommunityProjects);
207

  
208
          UIkit.notification('Project successfully removed!', {
209
            status: 'success',
210
            timeout: 6000,
211
            pos: 'bottom-right'
212
          });
213

  
214
          this.communityProjectsChanged.emit({
215
            value: this.communityProjects,
216
          });
217

  
218
          this.communitySearchUtils.totalResults--;
219
          this.communitySearchUtils.page=1;
220
          // this.createFunderFilter();
221
        },
222
        err => {
223
          this.handleError('An error has been occurred. Try again later!');
224
          console.error(err);
225
        },
226
        () => {
227

  
228
        }
229
      ));
230
    }
231
  }
232

  
233
  public removeProject(communityProject: any) {
234
    if(!Session.isLoggedIn()){
235
      this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
236
    } else {
237
      this.selectedCommunityProject = communityProject;
238
      this.alertModalDeleteCommunity.cancelButton = true;
239
      this.alertModalDeleteCommunity.okButton = true;
240
      this.alertModalDeleteCommunity.alertTitle = "Remove project?";
241
      let title = "";
242
      if(communityProject.name) {
243
        title = communityProject.name;
244
      }
245
      if(communityProject.name && communityProject.acronym) {
246
        title += " (";
247
      }
248
      if(communityProject.acronym) {
249
        title += communityProject.acronym;
250
      }
251
      if(communityProject.name && communityProject.acronym) {
252
        title += ")";
253
      }
254
      this.alertModalDeleteCommunity.message = "Project";
255
      if(title) {
256
        this.alertModalDeleteCommunity.message += " '"+title+"' ";
257
      }
258
      this.alertModalDeleteCommunity.message += "will be removed from your community. Are you sure?";
259
      this.alertModalDeleteCommunity.okButtonText = "Yes";
260
      this.alertModalDeleteCommunity.open();
261
    }
262
  }
263

  
264
  public initPreviewCommunityProjects() {
265
    this.previewCommunityProjects = this.communityProjects;
266
    this.sort();
267

  
268
    this.communitySearchUtils.totalResults = this.communityProjects.length;
269
    this.communitySearchUtils.status = this.errorCodes.DONE;
270

  
271
    this.disableForms = false;
272
    this.createFunderFilter();
273
  }
274

  
275
  public _getCommunityProjects(){
276
    if(!Session.isLoggedIn()){
277
      this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl":  this._router.url} });
278
    } else {
279
      this.communitySearchUtils.status = this.errorCodes.LOADING;
280
      this.disableForms = true;
281
      this.communityProjects = [];
282
      this.communitySearchUtils.totalResults = 0;
283
      this.communitySearchUtils.page=1;
284
      this.communitySearchUtils.keyword = "";
285
      this.selectedFunder = "";
286

  
287
      this.subscriptions.push(this._searchCommunityProjectsService.searchProjects(this.properties, this.portal).subscribe(
288
          data => {
289
            this.communityProjects = data;
290
            this.previewCommunityProjects = this.communityProjects;
291
            this.sort();
292

  
293
            this.communitySearchUtils.totalResults = data.length;
294
            this.communitySearchUtils.status = this.errorCodes.DONE;
295
            // if(this.communitySearchUtils.totalResults == 0 ){
296
            //   this.communitySearchUtils.status = this.errorCodes.NONE;
297
            // }
298
            this.disableForms = false;
299

  
300
            this.communityProjectsChanged.emit({
301
                value: this.communityProjects,
302
            });
303

  
304
            this.createFunderFilter();
305

  
306
            this.showLoading = false;
307
          },
308
          err => {
309
            console.error(err);
310
             //TODO check erros (service not available, bad request)
311

  
312
            if(err.status == '404') {
313
              this.communitySearchUtils.status = this.errorCodes.NOT_FOUND;
314
            } else if(err.status == '500') {
315
              this.communitySearchUtils.status = this.errorCodes.ERROR;
316
            } else {
317
              this.communitySearchUtils.status = this.errorCodes.NOT_AVAILABLE;
318
            }
319

  
320
            this.disableForms = false;
321
            this.showLoading = false;
322
          }
323
      ));
324
    }
325
  }
326

  
327
  public createFunderFilter(): Set<String> {
328
    this.funders = new Set<string>();
329
    this.allOptions = [];
330
    let i;
331
    for(i=0; i<this.communityProjects.length; i++) {
332
      let funder = this.communityProjects[i].funder;
333
      if(funder && !this.funders.has(funder)) {
334
        this.funders.add(funder);
335
        this.allOptions.push({label: funder, value: {id:funder, label: funder}});
336
      }
337
    }
338
    return this.funders;
339
  }
340

  
341
  public updatePage($event) {
342
    this.page = $event.value;
343
  }
344

  
345
  addNew() {
346
    this.toggleView.emit(null);
347
  }
348

  
349
  public applyFilters() {
350
    // this.page = 1;
351

  
352
    this.previewCommunityProjects = this.communityProjects.filter(project => {
353
      let return_value: boolean = (this.filterCommunityProjectByKeyword(project) && this.filterCommunityProjectByFunder(project));
354
      return return_value;
355
    });
356

  
357
    // check paging here!!!
358
    if(this.previewCommunityProjects.slice((this.page - 1)*this.pageSize, this.page*this.pageSize).length == 0) {
359
      this.page = 1;
360
    }
361

  
362
    this.sort();
363
  }
364

  
365
  public filterCommunityProjectByKeyword(project): boolean {
366
    const textFlag = this.searchText.toString().toLowerCase() === ''
367
            || (project.name.toLowerCase() || project.acronym || project.grantId || project.funder).match(this.searchText) != null;
368
    return textFlag;
369
  }
370

  
371
  public filterCommunityProjectByFunder(project): boolean {
372
    if(this.fundersCtrl.getRawValue().length == 0) {
373
      return true;
374
    }
375
    for (let funder of this.fundersCtrl.getRawValue()) {
376
      if (project.funder.toLowerCase().indexOf(funder.label.toLowerCase()) != -1) {
377
        return true;
378
      }
379
    }
380
    return false;
381
  }
382

  
383
  private sort() {
384
    // this.page = 1;
385
    let sortOption: { sort: string, descending: boolean } = this.filterForm.get('sort').value;
386

  
387
    this.previewCommunityProjects.sort((left, right): number => {
388
      if (sortOption.sort == "title") {
389
        if((left.name+left.acronym) > (right.name+right.acronym)) {
390
          return sortOption.descending ? -1 : 1;
391
        } else if((left.name+left.acronym) < (right.name+right.acronym)) {
392
          return sortOption.descending ? 1 : -1;
393
        }
394
      } else if (sortOption.sort == "grant") {
395
        if(left.grantId > right.grantId) {
396
          return sortOption.descending ? -1 : 1;
397
        } else if(left.grantId < right.grantId) {
398
          return sortOption.descending ? 1 : -1;
399
        }
400
      } else if (sortOption.sort == "funder") {
401
        if(left.funder > right.funder) {
402
          return sortOption.descending ? -1 : 1;
403
        } else if(left.funder < right.funder) {
404
          return sortOption.descending ? 1 : -1;
405
        }
406
      }
407

  
408
      return 0;
409
    });
410
  }
411

  
412
  public onSearchClose() {
413
    this.communitySearchUtils.keyword = this.filterForm.get('keyword').value;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff