Project

General

Profile

1
import {Component, ElementRef, Input, ViewChild} from '@angular/core';
2
import {ActivatedRoute, Router} from '@angular/router';
3
import {Location} from '@angular/common';
4
import {Meta, Title} from '@angular/platform-browser';
5
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
6

    
7
import {CommunityService} from "../openaireLibrary/connect/community/community.service";
8
import {ConfigurationService} from '../openaireLibrary/utils/configuration/configuration.service';
9
import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service';
10
import {SearchZenodoCommunitiesService} from '../openaireLibrary/connect/zenodoCommunities/searchZenodoCommunities.service';
11
import {ZenodoCommunitiesService} from '../openaireLibrary/connect/zenodoCommunities/zenodo-communities.service';
12
import {Session, User} from '../openaireLibrary/login/utils/helper.class';
13
import {StatisticsForDashboardComponent} from '../statistics/statistics.component';
14
import {StringUtils} from '../openaireLibrary/utils/string-utils.class';
15

    
16
import {PiwikHelper} from '../utils/piwikHelper';
17
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
18
import {SearchCommunityDataprovidersService} from "../openaireLibrary/connect/contentProviders/searchDataproviders.service";
19
import {SearchCommunityProjectsService} from "../openaireLibrary/connect/projects/searchProjects.service";
20
import {SearchResearchResultsService} from "../openaireLibrary/services/searchResearchResults.service";
21
import {RouterHelper} from "../openaireLibrary/utils/routerHelper.class";
22
import {SEOService} from "../openaireLibrary/sharedComponents/SEO/SEO.service";
23
import {UserManagementService} from "../openaireLibrary/services/user-management.service";
24
import {SubscribeComponent} from "../utils/subscribe/subscribe.component";
25
import {SearchCustomFilter} from "../openaireLibrary/searchPages/searchUtils/searchUtils.class";
26
import {FetchResearchResults} from "../openaireLibrary/utils/fetchEntitiesClasses/fetchResearchResults.class";
27
import {ErrorCodes} from "../openaireLibrary/utils/properties/errorCodes";
28
import {Subscription} from "rxjs";
29
import {properties} from "../../environments/environment";
30
import {ConnectHelper} from "../openaireLibrary/connect/connectHelper";
31
import {Filter} from "../openaireLibrary/searchPages/searchUtils/searchHelperClasses.class";
32

    
33
@Component({
34
  selector: 'community',
35
  templateUrl: 'community.component.html',
36
})
37

    
38
export class CommunityComponent {
39
  public url: string = null;
40
  
41
  public projectTotal = null;
42
  public contentProviderTotal = null;
43
  
44
  public projectsCalculated: boolean = false;
45
  public contentProvidersCalculated: boolean = false;
46
  
47
  params: any = {};
48
  properties: EnvProperties = properties;
49
  
50
  public errorCodes: ErrorCodes = new ErrorCodes();
51
  // Request results of each tab only the one time (first time tab is clicked)
52
  private reloadPublications: boolean = true;
53
  private reloadDatasets: boolean = true;
54
  private reloadSoftware: boolean = true;
55
  private reloadOrps: boolean = true;
56
  private reloadFeaturedDatasets: boolean = true;
57
  
58
  // Variables for publications, research data, projects, content providers, related content providers tabs
59
  public fetchPublications: FetchResearchResults;
60
  public fetchDatasets: FetchResearchResults;
61
  public fetchSoftware: FetchResearchResults;
62
  public fetchOrps: FetchResearchResults;
63
  public fetchFeaturedDatasets: FetchResearchResults;
64
  public searchNumber: number = 5;
65
  
66
  @Input() communityId = null;
67
  public community = null;
68
  
69
  public communityInfo = null;
70
  
71
  public showLoading: boolean = true;
72
  masterZenodoCommunity = null;
73
  zenodoCommunityIdS = [];
74
  showAllDescription = false;
75
  public thresholdDescription: number = 500;
76
  public descriptionDiff: number = 100;
77
  
78
  subscribers: number = 0;
79
  
80
  subs: Subscription[] = [];
81
  
82
  @ViewChild(StatisticsForDashboardComponent) statistics: StatisticsForDashboardComponent = null;
83
  public activeTab = "summary";
84
  public show: string = 'overview';
85
  public analyticsActiveTab: string = "";
86
  public analyticsChecked: boolean = false;
87
  
88
  searchLinkToResults: string = null;
89
  
90
  searchLinkToProjects: string = null;
91
  searchLinkToDataProviders: string = null;
92
  searchLinkToAdvancedResults: string = null;
93
  shareInZenodoPage: string = null;
94
  public routerHelper: RouterHelper = new RouterHelper();
95
  private user: User;
96
  selectedEntity;
97
  selectedEntitySimpleUrl;
98
  selectedEntityAdvancedUrl;
99
  keyword: string = "";
100
  customFilter;
101
  placeholderText = "Search by title, author, abstract, DOI, orcid... ";
102
  resultsQuickFilter: { filter: Filter, selected: boolean, filterId: string, value: string } = {
103
    filter: null,
104
    selected: true,
105
    filterId: "resultbestaccessright",
106
    value: "Open Access"
107
  };
108

    
109
  constructor(
110
    private element: ElementRef,
111
    private route: ActivatedRoute,
112
    private _router: Router,
113
    private location: Location,
114
    private _meta: Meta,
115
    private _title: Title,
116
    private _piwikService: PiwikService,
117
    private config: ConfigurationService,
118
    private _communityService: CommunityService,
119
    private _searchCommunityDataprovidersService: SearchCommunityDataprovidersService,
120
    private _searchCommunityProjectsService: SearchCommunityProjectsService,
121
    private _searchResearchResultsService: SearchResearchResultsService,
122
    private _searchZenodoCommunitiesService: SearchZenodoCommunitiesService,
123
    private _zenodoCommunitieService: ZenodoCommunitiesService,
124
    private seoService: SEOService,
125
    private userManagementService: UserManagementService) {
126
    
127
    var description = "OpenAIRE - Connect, Community Dashboard, research community";
128
    var title = "OpenAIRE - Connect";
129
    this._meta.updateTag({content: description}, "name='description'");
130
    this._meta.updateTag({content: description}, "property='og:description'");
131
    this._meta.updateTag({content: title}, "property='og:title'");
132
    this._title.setTitle(title);
133
    
134
    this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService);
135
    this.fetchDatasets = new FetchResearchResults(this._searchResearchResultsService);
136
    this.fetchSoftware = new FetchResearchResults(this._searchResearchResultsService);
137
    this.fetchOrps = new FetchResearchResults(this._searchResearchResultsService);
138
    this.fetchFeaturedDatasets = new FetchResearchResults(this._searchResearchResultsService);
139

    
140
  }
141
  
142
  public ngOnInit() {
143
    this.searchLinkToResults = this.properties.searchLinkToResults;
144
    this.searchLinkToProjects = this.properties.searchLinkToProjects;
145
    this.searchLinkToDataProviders = this.properties.searchLinkToDataProviders;
146
    this.searchLinkToAdvancedResults = this.properties.searchLinkToAdvancedResults;
147
    this.shareInZenodoPage = this.properties.shareInZenodoPage;
148
    this.url = properties.domain + properties.baseLink + this._router.url;
149
    this.seoService.createLinkForCanonicalURL(this.url, false);
150
    this._meta.updateTag({content: this.url}, "property='og:url'");
151
    this.subs.push(this.userManagementService.getUserInfo().subscribe(user => {
152
      this.user = user;
153
    }));
154
    this.customFilter = new SearchCustomFilter("Community", "communityId", this.communityId, "");
155
    this.subs.push(this._communityService.getCommunityAsObservable().subscribe(
156
      community => {
157
        this.community = community;
158
        if(community && !ConnectHelper.isPrivate(community, this.user)) {
159
          if (community.description != null && (community.description.length - this.thresholdDescription <= this.descriptionDiff)) {
160
            this.thresholdDescription = community.description.length;
161
          }
162
  
163
          if (this.properties.environment == "development") {
164
            this.params = {communityId: community.communityId};
165
          }
166
          this._meta.updateTag({content: community.description}, "name='description'");
167
          this._meta.updateTag({content: community.description}, "property='og:description'");
168
          this._meta.updateTag({content: community.title}, "property='og:title'");
169
          this._title.setTitle(community.title);
170
          if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) {
171
            this.subs.push(this._piwikService.trackView(this.properties, community.title, PiwikHelper.getSiteId(this.communityId, this.properties.environment)).subscribe());
172
          }
173
          if (this.community.zenodoCommunity) {
174
            this.subs.push(this._zenodoCommunitieService.getZenodoCommunityById(this.properties, this.properties.zenodoCommunities + this.community.zenodoCommunity, null).subscribe(
175
              result => {
176
                this.masterZenodoCommunity = result;
177
              },
178
              error => {
179
                this.handleError("Error getting Master Zenodo community with id: " + this.community.zenodoCommunity, error);
180
              }
181
            ));
182
          }
183
          this.subs.push(this._searchZenodoCommunitiesService.searchZCommunities(this.properties, this.communityId).subscribe(
184
            result => {
185
              this.zenodoCommunityIdS = result;
186
            },
187
            error => {
188
              this.handleError("Error getting list of zenodo communities for community with openaire id: " + this.communityId, error);
189
            }
190
          ));
191
        }
192
      }));
193
    
194
    this.countResearchResults("publication");
195
    this.countResearchResults("dataset");
196
    this.countResearchResults("software");
197
    this.countResearchResults("other");
198
    if(this.communityId == "enermaps"){
199
      this.countResearchResults("dataset", "enermaps::selection" );
200
    }
201
    
202
    this.subs.push(this._searchCommunityProjectsService.countTotalProjects(this.properties, this.communityId).subscribe(
203
      projectTotal => {
204
        this.projectTotal = projectTotal;
205
      },
206
      error => {
207
        this.handleError("Error getting number of projects for community with id: " + this.communityId, error);
208
      },
209
      () => {
210
        this.projectsCalculated = true;
211
      }
212
    ));
213
    
214
    this.subs.push(this._searchCommunityDataprovidersService.countTotalDataproviders(this.properties, this.communityId).subscribe(
215
      contentProviderTotal => {
216
        this.contentProviderTotal = contentProviderTotal;
217
        //console.log(contentProviderTotal);
218
      },
219
      error => {
220
        this.handleError("Error getting number of content providers for community with id: " + this.communityId, error);
221
      },
222
      () => {
223
        this.contentProvidersCalculated = true;
224
      }
225
    ));
226
    this.subs.push(this.config.communityInformationState.subscribe(
227
      res => {
228
        this.communityInfo = res;
229
      },
230
      error => {
231
        //console.log(error)
232
        this.handleError("Error getting community with id: " + this.communityId, error);
233
      }
234
    ));
235
  }
236
  
237
  private searchPublications(page: number, size: number) {
238
    this.setActiveTab("publication");
239
    
240
    if (this.reloadPublications &&
241
      (this.fetchPublications.searchUtils.status == this.errorCodes.LOADING ||
242
        (this.fetchPublications.searchUtils.status == this.errorCodes.DONE && this.fetchPublications.searchUtils.totalResults > 0)
243
      )
244
    ) {
245
      this.fetchPublications.getResultsForCommunity("publication", this.communityId, page, size, this.properties);
246
    }
247
    this.reloadPublications = false;
248
  }
249
  
250
  private searchDatasets(page: number, size: number) {
251
    this.setActiveTab("dataset");
252
    
253
    if (this.reloadDatasets &&
254
      (this.fetchDatasets.searchUtils.status == this.errorCodes.LOADING ||
255
        (this.fetchDatasets.searchUtils.status == this.errorCodes.DONE && this.fetchDatasets.searchUtils.totalResults > 0)
256
      )
257
    ) {
258
      this.fetchDatasets.getResultsForCommunity("dataset", this.communityId, page, size, this.properties);
259
    }
260
    this.reloadDatasets = false;
261
  }
262
  
263
  private searchSoftware(page: number, size: number) {
264
    this.setActiveTab("software");
265
    
266
    if (this.reloadSoftware &&
267
      (this.fetchSoftware.searchUtils.status == this.errorCodes.LOADING ||
268
        (this.fetchSoftware.searchUtils.status == this.errorCodes.DONE && this.fetchSoftware.searchUtils.totalResults > 0)
269
      )
270
    ) {
271
      this.fetchSoftware.getResultsForCommunity("software", this.communityId, page, size, this.properties);
272
    }
273
    this.reloadSoftware = false;
274
  }
275
  
276
  private searchOrps(page: number, size: number) {
277
    this.setActiveTab("other");
278
    
279
    if (this.reloadOrps &&
280
      (this.fetchOrps.searchUtils.status == this.errorCodes.LOADING ||
281
        (this.fetchOrps.searchUtils.status == this.errorCodes.DONE && this.fetchOrps.searchUtils.totalResults > 0)
282
      )
283
    ) {
284
      this.fetchOrps.getResultsForCommunity("other", this.communityId, page, size, this.properties);
285
    }
286
    this.reloadOrps = false;
287
  }
288
  private searchFeaturedDatasets(page: number, size: number) {
289
    this.setActiveTab("enermaps");
290
    if (this.reloadFeaturedDatasets &&
291
      (this.fetchFeaturedDatasets.searchUtils.status == this.errorCodes.LOADING ||
292
        (this.fetchFeaturedDatasets.searchUtils.status == this.errorCodes.DONE && this.fetchFeaturedDatasets.searchUtils.totalResults > 0)
293
      )
294
    ) {
295
      this.fetchFeaturedDatasets.getAllResultsForCommunity("dataset", this.communityId, page, size, this.properties, "enermaps::selection");
296
    }
297
    this.reloadFeaturedDatasets = false;
298
  }
299
  
300
  private countResearchResults(resultType: string, contextId = null) {
301
    let fetch: FetchResearchResults;
302
    
303
    if (resultType == "publication") {
304
      fetch = this.fetchPublications;
305
    } else if (resultType == "dataset" && !contextId) {
306
      fetch = this.fetchDatasets;
307
    } else if (resultType == "software") {
308
      fetch = this.fetchSoftware;
309
    } else if (resultType == "other") {
310
      fetch = this.fetchOrps;
311
    } else if (resultType == "dataset" && contextId) {
312
      fetch = this.fetchFeaturedDatasets;
313
      this.fetchFeaturedDatasets.getAllResultsForCommunity("dataset", this.communityId, 0, 0, this.properties, contextId);
314
      return;
315
    }
316
    fetch.getNumForCommunity(resultType, this.communityId, this.properties, contextId);
317
  }
318
  
319
  public ngOnDestroy() {
320
    for (let sub of this.subs) {
321
      sub.unsubscribe();
322
    }
323
    this.fetchPublications.clearSubscriptions();
324
    this.fetchDatasets.clearSubscriptions();
325
    this.fetchOrps.clearSubscriptions();
326
    this.fetchSoftware.clearSubscriptions();
327
    this.fetchFeaturedDatasets.clearSubscriptions();
328
  }
329
  
330
  isEntityEnabled(entity: string) {
331
    return this.communityInfo.entities.some(x => x['pid'] == entity && x['isEnabled'] === true);
332
  }
333
  
334
  isRouteEnabled(route: string) {
335
    return this.communityInfo.pages.some(x => x['route'] == route && x['isEnabled'] === true);
336
  }
337
  
338
  showInvite() {
339
    return this.isManager();
340
  }
341
  
342
  isManager() {
343
    if (!this.user) {
344
      return false;
345
    }
346
    var email = this.user.email;
347
    var index = -1;
348
    if (email && this.community != null && this.community.managers != null) {
349
      index = this.community.managers.indexOf(email);
350
    }
351
    return Session.isPortalAdministrator(this.user) || Session.isCommunityCurator(this.user) || index != -1;
352
  }
353
  
354
  private handleError(message: string, error) {
355
    console.error("Community (component): " + message, error);
356
  }
357
  
358
  getSearchPlaceHolder() {
359
    var entities = [];
360
    if (this.isEntityEnabled("publication")) {
361
      entities.push("publications");
362
    }
363
    if (this.isEntityEnabled("dataset")) {
364
      entities.push("research data");
365
    }
366
    if (this.isEntityEnabled("software")) {
367
      entities.push("software");
368
    }
369
    if (this.isEntityEnabled("orp")) {
370
      entities.push("other research products");
371
    }
372
    return "Search" + ((entities.length > 0) ? (" for " + entities.join(', ') + "...") : "");
373
  }
374
  
375
  countOtherGraphs() {
376
    var count = 0;
377
    if (this.statistics && this.statistics.allowedEntities) {
378
      for (var entity of this.statistics.allowedEntities) {
379
        if (this.statistics.statisticsSum[entity].total > 0 && this.statistics.allowedCharts[entity].length > 0 && this.activeTab != entity) {
380
          count += this.statistics.allowedCharts[entity].length;
381
        }
382
      }
383
    }
384
    return count;
385
  }
386
  
387
  createParams(param) {
388
    return StringUtils.quote(StringUtils.URIEncode(param));
389
  }
390
  
391
  private setActiveTab(entityType: string) {
392
    if (entityType == "other") {
393
      this.activeTab = "orp";
394
    } else {
395
      this.activeTab = entityType;
396
    }
397
  }
398
  
399
  public getParamsForSearchLink(type: string = "") {
400
    if (type) {
401
      return this.routerHelper.createQueryParams(['type', 'qf', 'sortBy'], [type, 'false', 'resultdateofacceptance,descending']);
402
    } else {
403
      return {};
404
    }
405
  }
406
  
407
  private getEntityName(entityType: string, plural: boolean, full: boolean): string {
408
    if (entityType == "publication") {
409
      return "publication" + (plural ? "s" : "");
410
    } else if (entityType == "dataset") {
411
      return (full ? "research data" : ("dataset" + (plural ? "s" : "")));
412
    } else if (entityType == "software") {
413
      return "software";
414
    } else if (entityType == "other") {
415
      return (full ? ("other research product" + (plural ? "s" : "")) : "other");
416
    }
417
  }
418
  
419
  public buildProjectsAndContentProvidesTooltip(): string {
420
    let tooltipContent: string = "<div class='uk-margin'>";
421
    
422
    if (this.projectTotal != null && this.projectTotal > 0 && this.isEntityEnabled('project') && this.isRouteEnabled(this.searchLinkToProjects)) {
423
      tooltipContent += "<span class='uk-text-bold'>Projects</span>";
424
    }
425
    if (this.projectTotal != null && this.projectTotal > 0 && this.isEntityEnabled('project') && this.isRouteEnabled(this.searchLinkToProjects)
426
      && (this.contentProviderTotal != null && this.contentProviderTotal > 0 && this.isEntityEnabled('datasource') && this.isRouteEnabled(this.searchLinkToDataProviders))) {
427
      tooltipContent += " and ";
428
    }
429
    if (this.contentProviderTotal != null && this.contentProviderTotal > 0 && this.isEntityEnabled('datasource') && this.isRouteEnabled(this.searchLinkToDataProviders)) {
430
      tooltipContent += "<span class='uk-text-bold'>Content Providers</span>";
431
    }
432
    
433
    tooltipContent += " have been selected as relevant for your community by the gateway curators.";
434
    tooltipContent += "</div>";
435
    
436
    return tooltipContent;
437
  }
438
  
439
  public buildZenodoCommunitiesTooltip(): string {
440
    let tooltipContent: string = "<div class='uk-margin'>";
441
    
442
    tooltipContent += "<span class='uk-text-bold'>Zenodo</span> is a catch-all repository for OpenAIRE.";
443
    tooltipContent += "<div class='uk-margin-small-top'>A <span class='uk-text-bold'>Zenodo Community</span> is created and curated by Zenodo users.</div>";
444
    tooltipContent += "</div>";
445
    return tooltipContent;
446
  }
447
  
448
  entityChanged($event) {
449
    this.selectedEntity = $event.entity;
450
    this.selectedEntitySimpleUrl = $event.simpleUrl;
451
    this.selectedEntityAdvancedUrl = $event.advancedUrl;
452
    if (this.selectedEntity == 'result') {
453
      this.placeholderText = "Search by title, author, abstract, DOI, orcid... ";
454
    } else if (this.selectedEntity == 'project') {
455
      this.placeholderText = "Search by project title, grant id, funder...";
456
    } else if (this.selectedEntity == 'dataprovider') {
457
      this.placeholderText = "Search by name...";
458
    } else {
459
      this.placeholderText = "Search community content";
460
    }
461
  }
462
  
463
  goTo(simple: boolean) {
464
    let url = (simple) ? this.selectedEntitySimpleUrl : this.selectedEntityAdvancedUrl;
465
    let parameterNames = [];
466
    let parameterValues = [];
467

    
468
    if (this.selectedEntity == "result" && this.resultsQuickFilter && this.resultsQuickFilter.selected) {
469
      parameterNames.push(this.resultsQuickFilter.filterId);
470
      parameterValues.push('"'+ encodeURIComponent(this.resultsQuickFilter.value)+'"');
471
    }
472

    
473
    if (this.keyword.length > 0) {
474
      parameterNames.push("fv0");
475
      parameterValues.push(this.keyword);
476
      parameterNames.push("f0");
477
      parameterValues.push("q");
478
    }
479
    this._router.navigate([url], {queryParams: this.routerHelper.createQueryParams(parameterNames, parameterValues)});
480
  }
481
  
482
  public countSubscribersEvent($event) {
483
    this.subscribers = $event.value;
484
  }
485
  
486
  public checkStatistics(type: string) {
487
    return !!(this.isEntityEnabled(type)
488
      && this.statistics && this.statistics.statisticsDisplay && this.statistics.statisticsDisplay.isActive
489
      && this.statistics.statisticsSum && this.statistics.statisticsSum[type] && this.statistics.statisticsSum[type].total > 0
490
      &&
491
      (this.statistics.statisticsDisplay.entities[type].numbers.map['total']['showInMonitor']
492
        || this.statistics.statisticsDisplay.entities[type].numbers.map['project']['showInMonitor']
493
        || this.statistics.statisticsDisplay.entities[type].numbers.map['open']['showInMonitor']
494
        || this.statistics.statisticsDisplay.entities[type].numbers.map['closed']['showInMonitor']
495
        || this.statistics.statisticsDisplay.entities[type].numbers.map['embargo']['showInMonitor']
496
        || this.statistics.statisticsDisplay.entities[type].numbers.map['restricted']['showInMonitor']
497
        || (this.statistics.allowedEntitiesMode['showInMonitor']
498
          && this.statistics.allowedChartsMode['showInMonitor'][type]
499
          && this.statistics.allowedChartsMode['showInMonitor'][type].length > 0)));
500
  }
501
  
502
  public initializeAnalyticsActiveTab() {
503
    if (!this.analyticsChecked) {
504
      if (this.checkStatistics("publication")) {
505
        this.analyticsActiveTab = "publication";
506
      } else if (this.checkStatistics("dataset")) {
507
        this.analyticsActiveTab = "dataset";
508
      } else if (this.checkStatistics("software")) {
509
        this.analyticsActiveTab = "software";
510
      } else if (this.checkStatistics("orp")) {
511
        this.analyticsActiveTab = "orp";
512
      }
513
    }
514
  }
515
  
516
  public showAnalyticsTab() {
517
    this.initializeAnalyticsActiveTab();
518
    return this.analyticsActiveTab;
519
  }
520
  
521
  public onSelectActiveTab(activeTabId) {
522
    if (this.activeTab != "activaTabId") {   // tab really changed
523
      if (activeTabId == 'summary') {
524
        this.activeTab = 'summary';
525
      } else if (activeTabId == 'publications') {
526
        this.show = 'overview';
527
        this.searchPublications(1, this.searchNumber);
528
      } else if (activeTabId == 'datasets') {
529
        this.show = 'overview';
530
        this.searchDatasets(1, this.searchNumber);
531
      } else if (activeTabId == 'software') {
532
        this.show = 'overview';
533
        this.searchSoftware(1, this.searchNumber);
534
      } else if (activeTabId == 'other') {
535
        this.show = 'overview';
536
        this.searchOrps(1, this.searchNumber);
537
      } else if (activeTabId == 'analytics') {
538
        this.show = 'analysis';
539
        this.activeTab = 'analytics';
540
        this.analyticsChecked = true;
541
      } else if (activeTabId == 'mapping') {
542
        this.show = 'mapping';
543
        this.activeTab = 'mapping';
544
      } else if (activeTabId == 'enermaps') {
545
        this.show = 'enermaps';
546
        this.searchFeaturedDatasets(1, this.fetchFeaturedDatasets.searchUtils.totalResults < 20?this.fetchFeaturedDatasets.searchUtils.totalResults:20);
547
      }
548
    }
549
  }
550
  isPrivate(){
551
    return ConnectHelper.isPrivate(this.community, this.user);
552
  }
553
}
(3-3/4)