diff --git a/frontend/src/app/data.service.ts b/frontend/src/app/data.service.ts
index e8a077a..b6d2508 100644
--- a/frontend/src/app/data.service.ts
+++ b/frontend/src/app/data.service.ts
@@ -188,6 +188,24 @@ export class DataService {
return repoData;
}
+ async loadAllInstitutionsSummaries() {
+ const institutionData = await this.http
+ .get<{
+ institutionsSummaries: InstitutionSummary[];
+ total: number;
+ }>(`${environment.api}api/completeInstitutionSummaries`, {})
+ .pipe(
+ catchError(error => {
+ if (error.status === 401) {
+ this.toastr.error("Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.", "Login timeout", {disableTimeOut: true});
+ }
+ return throwError(error);
+ })
+ )
+ .toPromise();
+ return institutionData;
+ }
+
// request to get all users, repositories, institutions and organizations,
// these are used to get all the data for excel export and is restricted to logged in users
// *****************************************************************************************************
diff --git a/frontend/src/app/ranking/ranking.component.html b/frontend/src/app/ranking/ranking.component.html
index 7c2fdcc..6440c0d 100644
--- a/frontend/src/app/ranking/ranking.component.html
+++ b/frontend/src/app/ranking/ranking.component.html
@@ -58,6 +58,11 @@
(change)="includeForksChange($event.checked)"
>Include forks
+
+
Information on OSS Benchmark updated: {{ latestUdpate | date }}
diff --git a/frontend/src/app/ranking/ranking.component.ts b/frontend/src/app/ranking/ranking.component.ts
index 331211f..60f1649 100644
--- a/frontend/src/app/ranking/ranking.component.ts
+++ b/frontend/src/app/ranking/ranking.component.ts
@@ -36,6 +36,7 @@ export class RankingComponent implements OnInit {
recordFilter = '';
state: Date;
completeInstitutions: Institution[];
+ allInstitutions: InstitutionSumary[] = [];
institutions: InstitutionSumary[];
window: any = window;
includeForks: boolean = false;
@@ -45,6 +46,7 @@ export class RankingComponent implements OnInit {
sortDirection: 'ASC' | 'DESC' = 'DESC';
latestUdpate: any;
exportService: DataExportService = new DataExportService();
+ isDownloading: boolean = false;
searchTermRaw: string = '';
@@ -198,6 +200,33 @@ export class RankingComponent implements OnInit {
this.reloadData();
}
+ isLoggedIn(): boolean {
+ return this.authService.isUserLoggedIn();
+ }
+
+ async downloadData(): Promise {
+ this.isDownloading = true;
+ try {
+ let institutionData = await this.dataService.loadAllInstitutionsSummaries();
+ console.log('institutionData', institutionData);
+ this.allInstitutions = institutionData.institutionsSummaries;
+
+ // Format the date fields
+ this.allInstitutions = this.allInstitutions.map((institution) => {
+ if (institution.created_at) {
+ institution.created_at = this.exportService.formatDate(institution.created_at);
+ }
+ return institution;
+ });
+
+ this.exportService.exportData(this.allInstitutions, 'InstitutionRanking');
+ } catch (error) {
+ console.error('Error occurred while downloading data:', error);
+ } finally {
+ this.isDownloading = false;
+ }
+ }
+
@ViewChild(MatPaginator) paginator: MatPaginator;
diff --git a/oss-api/src/api/api.controller.ts b/oss-api/src/api/api.controller.ts
index 7cf7f15..ecec3f1 100644
--- a/oss-api/src/api/api.controller.ts
+++ b/oss-api/src/api/api.controller.ts
@@ -135,6 +135,32 @@ export class ApiController {
return { users, total: users.length };
}
+ // Institutions Data
+ //@UseGuards(AuthGuard)
+ @Get('completeInstitutionSummaries')
+ async collectInstitutionSummaries() {
+ const queryConfig = {
+ sector: [],
+ search: '',
+ sort: 'num_repos',
+ direction: 'DESC',
+ page: 0,
+ count: -1,
+ sendStats: false,
+ includeForks: false,
+ };
+ const institutionsSummaries =
+ await this.mongoDbService.findInstitutionsWithConditions(
+ queryConfig.sort,
+ queryConfig.direction == 'ASC' ? 1 : -1,
+ queryConfig.count,
+ queryConfig.page,
+ queryConfig.includeForks,
+ [{}],
+ );
+ return { institutionsSummaries, total: institutionsSummaries.length };
+ }
+
/***********************************Helper************************************************/
/**
* Handle the instiution query with the given conditions
@@ -150,7 +176,7 @@ export class ApiController {
return queryConfig.sector.includes(sector);
});
}
- let conditions: Object[] = [
+ const conditions: Object[] = [
{
sector: { $in: sectorList },
},
@@ -160,7 +186,7 @@ export class ApiController {
$text: { $search: queryConfig.search },
});
}
- let institutions = await this.mongoDbService.findInstitutionsWithConditions(
+ const institutions = await this.mongoDbService.findInstitutionsWithConditions(
queryConfig.sort,
queryConfig.direction == 'ASC' ? 1 : -1,
queryConfig.count,
@@ -168,7 +194,7 @@ export class ApiController {
queryConfig.includeForks,
conditions,
);
- let foundSectors =
+ const foundSectors =
await this.mongoDbService.countInstitutionsWithConditions(conditions);
let total = 0;
const sectorcount = {};
diff --git a/oss-api/src/mongo-db/mongo-db.service.ts b/oss-api/src/mongo-db/mongo-db.service.ts
index fa2288c..59c0f78 100644
--- a/oss-api/src/mongo-db/mongo-db.service.ts
+++ b/oss-api/src/mongo-db/mongo-db.service.ts
@@ -4,7 +4,7 @@ import {
OnApplicationShutdown,
OnModuleInit,
} from '@nestjs/common';
-import { MongoClient, ConnectOptions, ObjectId } from 'mongodb';
+import { MongoClient, ConnectOptions, ObjectId, Document } from 'mongodb';
import {
Institution,
Repository,
@@ -138,130 +138,132 @@ export class MongoDbService implements OnApplicationShutdown, OnModuleInit {
// this.logger.log(
// `Searching for institutions with these conditions: ${conditions.toString()}`,
// );
- return this.client
- .db(this.database)
- .collection(Tables.institutions)
- .aggregate(
- [
- {
- $match: {
- $and: conditions,
- },
- },
- {
- $lookup: {
- from: 'organisation',
- localField: 'orgs',
- foreignField: '_id',
- as: 'orga',
- },
- },
- { $unwind: { path: '$orga', preserveNullAndEmptyArrays: true } },
- {
- $lookup: {
- from: 'repositoriesNew',
- localField: 'orga.repos',
- foreignField: '_id',
- as: 'repo',
- },
- },
- {
- $project: {
- shortname: 1,
- name_de: 1,
- avatar: 1,
- sector: 1,
- orga: 1,
- repo: {
- $cond: [
- { $eq: [includeForks, true] },
- '$repo',
- {
- $filter: {
- input: '$repo',
- as: 'repository',
- cond: {
- $eq: ['$$repository.fork', false],
- },
- },
- },
- ],
- },
- },
- },
- { $unwind: { path: '$repo', preserveNullAndEmptyArrays: true } },
- // { $sort: { 'orga.created_at': 1 } }, // comment out to make "include forks" checkbox work
- {
- $group: {
- _id: '$_id',
- shortname: { $first: '$shortname' },
- name_de: { $first: '$name_de' },
- num_repos: { $count: {} },
- members: { $push: '$repo.contributors' },
- forks: { $push: '$repo.fork' },
- avatar: { $first: { $first: '$avatar' } },
- sector: { $first: '$sector' },
- repo_names: { $push: '$repo.name' },
- location: { $first: '$orga.locations' },
- created_at: { $first: '$orga.created_at' },
- },
- },
- {
- $set: {
- total_num_forks_in_repos: {
- $sum: {
- $size: {
- $filter: {
- input: '$forks',
- cond: '$$this',
- },
+ const aggregateOptions: Document[] = [
+ {
+ $match: {
+ $and: conditions,
+ },
+ },
+ {
+ $lookup: {
+ from: 'organisation',
+ localField: 'orgs',
+ foreignField: '_id',
+ as: 'orga',
+ },
+ },
+ { $unwind: { path: '$orga', preserveNullAndEmptyArrays: true } },
+ {
+ $lookup: {
+ from: 'repositoriesNew',
+ localField: 'orga.repos',
+ foreignField: '_id',
+ as: 'repo',
+ },
+ },
+ {
+ $project: {
+ shortname: 1,
+ name_de: 1,
+ avatar: 1,
+ sector: 1,
+ orga: 1,
+ repo: {
+ $cond: [
+ { $eq: [includeForks, true] },
+ '$repo',
+ {
+ $filter: {
+ input: '$repo',
+ as: 'repository',
+ cond: {
+ $eq: ['$$repository.fork', false],
},
},
},
- num_members: {
- $size: {
- $setUnion: [
- {
- $reduce: {
- input: '$members',
- initialValue: [],
- in: { $concatArrays: ['$$value', '$$this'] },
- },
- },
- [],
- ],
+ ],
+ },
+ },
+ },
+ { $unwind: { path: '$repo', preserveNullAndEmptyArrays: true } },
+ // { $sort: { 'orga.created_at': 1 } }, // comment out to make "include forks" checkbox work
+ {
+ $group: {
+ _id: '$_id',
+ shortname: { $first: '$shortname' },
+ name_de: { $first: '$name_de' },
+ num_repos: { $count: {} },
+ members: { $push: '$repo.contributors' },
+ forks: { $push: '$repo.fork' },
+ avatar: { $first: { $first: '$avatar' } },
+ sector: { $first: '$sector' },
+ repo_names: { $push: '$repo.name' },
+ location: { $first: '$orga.locations' },
+ created_at: { $first: '$orga.created_at' },
+ },
+ },
+ {
+ $set: {
+ total_num_forks_in_repos: {
+ $sum: {
+ $size: {
+ $filter: {
+ input: '$forks',
+ cond: '$$this',
},
},
},
},
- {
- $project: {
- _id: 1,
- shortname: 1,
- name_de: 1,
- num_repos: 1,
- num_members: 1,
- total_num_forks_in_repos: 1,
- avatar: 1,
- sector: 1,
- repo_names: 1,
- location: 1,
- created_at: 1,
+ num_members: {
+ $size: {
+ $setUnion: [
+ {
+ $reduce: {
+ input: '$members',
+ initialValue: [],
+ in: { $concatArrays: ['$$value', '$$this'] },
+ },
+ },
+ [],
+ ],
},
},
- {
- $sort: { [sortKey]: direction },
- },
- {
- $skip: limit * page,
- },
- {
- $limit: limit,
- },
- ],
+ },
+ },
+ {
+ $project: {
+ _id: 1,
+ shortname: 1,
+ name_de: 1,
+ num_repos: 1,
+ num_members: 1,
+ total_num_forks_in_repos: 1,
+ avatar: 1,
+ sector: 1,
+ repo_names: 1,
+ location: 1,
+ created_at: 1,
+ },
+ },
+ {
+ $sort: { [sortKey]: direction },
+ },
+ {
+ $skip: limit * page,
+ },
+ ];
+
+ if(limit > 0) {
+ aggregateOptions.push({$limit: limit})
+ }
+
+ return this.client
+ .db(this.database)
+ .collection(Tables.institutions)
+ .aggregate(aggregateOptions,
{
allowDiskUse: true,
- },
+ }
)
.toArray() as Promise;
}