develop #2

Merged
andreas.mantas merged 6 commits from develop into master 2024-04-04 15:10:25 +02:00
10 changed files with 130 additions and 37 deletions

108
README.md
View File

@ -1,32 +1,110 @@
# UOA Repository Manager UI # UOA Repository Manager UI
## Introduction
## Architecture
## Building
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.8 (Angular version 6.1.10). This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.8 (Angular version 6.1.10).
## Minimum requirements for installing and building the project #### Minimum requirements for installing and building the project
[Node.js](https://nodejs.org/en/) version 8.x or 10.x.<br> [Node.js](https://nodejs.org/en/) version 8.x or 10.x.<br>
[npm client](https://docs.npmjs.com/cli/install) command line interface (it is installed with Node.js by default). [npm client](https://docs.npmjs.com/cli/install) command line interface (it is installed with Node.js by default).
- [Node.js version 16](https://nodejs.org/en/blog/release/v16.16.0)
## Installing the project ###### Build Instructions:
Follow the instructions below to download the source code and build the application.
For more information about building an Angular app you can refer to the official documentation: [Building and serving Angular apps](https://angular.io/guide/build#building-and-serving-angular-apps).
After checking out (or updating) the repository enter the created folder and run `npm ci`. 1. Clone the repository and move inside the directory
This will install the exact versions of the dependencies as mentioned in the `package-lock.json` file (inside the root folder). <br> `git clone https://code-repo.d4science.org/MaDgIK/uoa-repository-manager-ui.git && cd uoa-repository-manager-ui`
2. Install Angular dependencies
<br> `npm install`
3. Build Angular app
<br> `ng build --configuration production`
<br> Produces the directory "dist/**uoa-repository-manager-ui**" which contains the compiled files.
<br>
<br>
## Build for production ## Deployment
Run `npm run build` (equivalent of `ng build --prod`) to build the project. The build artifacts will be stored in the `dist/uoa-repository-manager-ui` directory. ### Prerequisites
- Nginx
## Deploy project to nginx server ### Instructions
To deploy the Frontend app:
1. Make sure that you have successfully built and installed the application on Nginx (or another Web Server).
2. _Start_ or _reload_ the Web Server service.
<br>e.g. `systemctl start nginx` or `systemctl reload nginx`
Run `tar -czvf dist.tar.gz dist/` to generate a compressed `.gz` file containing the built angular folder<br> ## Installation
Run `scp dist.tar.gz path/to/server/` to copy the compressed file to the server.<br>
Connect to server (`ssh user@server.ip.address`).<br>
Uncompress `dist.tar.gz` file.<br>
Navigate to the root folder of the server.
Copy the contents of the uncompressed dist/uoa-repository-manager-ui folder
into the `uoa-repository-manager-dashboard` folder (superuser privileges are normally required for this action).<br>
## Other topics ### Prerequisites
- [Nginx](https://www.nginx.com/) (or another Web Server like [Apache HTTP Server](https://httpd.apache.org/))
<br>
<br>
### Installation
#### Nginx Configuration
You have to create a [Server Block configuration](https://www.nginx.com/resources/wiki/start/topics/examples/server_blocks/) that will point to the directory "dist/**uoa-repository-manager-ui**" created by [building manually](./building.md#manual-build) the webapp.
It must also be configured as a reverse proxy for the Backend Application (to serve it under the path '/api') and for the list of [Dependencies](#dependencies) of the project.
See the example below:
```nginx
server {
server_name ...
access_log ...
root /path/to/uoa-repository-manager-ui; # the directory of the application
location / {
try_files $uri$args $uri$args/ /index.html /index.php;
}
location ~* \.(eot|ttf|woff)$ {
add_header Access-Control-Allow-Origin *;
}
# reverse proxy configuration for the backend application
location /api {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass <?>;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
}
[...]
}
```
Lastly, we would advice to validate the configuration of the Nginx to make sure it does not contain errors.
<br>Execute `nginx -t` with elevated permissions to perform a validation. If the test is successful you can move on to [deploying](./deployment.md#frontend) the application.
<br>
<br>
## Configuration
## Security
## Maintenance
## Recovery
## References
## Other topics
### Development server ### Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.<br> Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.<br>

View File

@ -678,11 +678,12 @@ export class Typology {
} }
export class AggregationDetails implements IsSerializable { export class AggregationDetails implements IsSerializable {
aggregationStage: string;
date: Date; date: Date;
numberOfRecords: number; aggregationStage: string; // is present when aggregationStage==='COLLECT'
collectionMode: string; collectionMode: string;
numberOfRecords: number;
indexedVersion: boolean; indexedVersion: boolean;
completedSuccessfully: boolean;
} }
export class Aggregations implements IsSerializable { export class Aggregations implements IsSerializable {

View File

@ -53,7 +53,7 @@ export class HomeComponent implements OnInit {
if (this.authService.getIsUserLoggedIn()) { if (this.authService.getIsUserLoggedIn()) {
this.router.navigate([pageUrl]); this.router.navigate([pageUrl]);
} else { } else {
this.authService.redirectUrl = pageUrl; // this.authService.redirectUrl = pageUrl;
this.login(); this.login();
} }
} }

View File

@ -51,8 +51,8 @@
<!--<td class="uk-text-center"><img class="md-user-image dense-image dense-ready" src="assets/img/avatars/avatar_01_tn@2x.png" alt="" data-dense-cap="2"></td>--> <!--<td class="uk-text-center"><img class="md-user-image dense-image dense-ready" src="assets/img/avatars/avatar_01_tn@2x.png" alt="" data-dense-cap="2"></td>-->
<td><span *ngIf="aggr.date">{{ aggr.date | date : "yyyy-MM-dd" }}</span></td> <td><span *ngIf="aggr.date">{{ aggr.date | date : "yyyy-MM-dd" }}</span></td>
<td class=""><span *ngIf="aggr.aggregationStage">{{ aggr.aggregationStage }}</span></td> <td class=""><span *ngIf="aggr.aggregationStage">{{ aggr.aggregationStage }}</span></td>
<td class=""><span *ngIf="aggr.collectionMode">{{ aggr.collectionMode }}</span></td> <td class=""><span>{{ aggr.collectionMode ? aggr.collectionMode : '-'}}</span></td>
<td class="uk-text-center"><span *ngIf="aggr.numberOfRecords">{{ aggr.numberOfRecords }}</span></td> <td class="uk-text-center"><span *ngIf="aggr.numberOfRecords !== null">{{ aggr.numberOfRecords }}</span></td>
<td class="uk-text-center"><span *ngIf="aggr.indexedVersion !== null && (aggr.indexedVersion === true)" class="uk-badge">Indexed version</span></td> <td class="uk-text-center"><span *ngIf="aggr.indexedVersion !== null && (aggr.indexedVersion === true)" class="uk-badge">Indexed version</span></td>
</tr> </tr>
</tbody> </tbody>

View File

@ -74,7 +74,7 @@
<span class="uk-text-small uk-text-muted">{{ aggr.collectionMode }}</span> <span class="uk-text-small uk-text-muted">{{ aggr.collectionMode }}</span>
</div> </div>
</li> </li>
<li *ngIf="aggr.numberOfRecords"> <li>
<!--<div class="md-list-addon-element">--> <!--<div class="md-list-addon-element">-->
<!--<span class="md-user-image md-list-addon-avatar dense-image dense-ready">--> <!--<span class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">list</i>--> <!--<i class="material-icons">list</i>-->
@ -82,7 +82,13 @@
<!--</div>--> <!--</div>-->
<div class="md-list-content"> <div class="md-list-content">
<span class="md-list-heading">Number of records</span> <span class="md-list-heading">Number of records</span>
<span class="uk-text-small uk-text-muted">{{ aggr.numberOfRecords }}</span> <span class="uk-text-small uk-text-muted">{{ aggr?.numberOfRecords>=0 ? aggr.numberOfRecords : 'NA' }}</span>
</div>
</li>
<li>
<div class="md-list-content">
<span class="md-list-heading">Completed Successfully</span>
<span class="uk-text-small uk-text-muted">{{ aggr.completedSuccessfully }}</span>
</div> </div>
</li> </li>
</ul> </ul>

View File

@ -144,7 +144,7 @@
</div> </div>
</div> </div>
<div *ngIf="aggr.numberOfRecords" class="uk-margin-small-bottom"> <div class="uk-margin-small-bottom">
<!--<div class="inline-block" style="vertical-align: top">--> <!--<div class="inline-block" style="vertical-align: top">-->
<!--<span class="md-user-image md-list-addon-avatar dense-image dense-ready">--> <!--<span class="md-user-image md-list-addon-avatar dense-image dense-ready">-->
<!--<i class="material-icons">list</i>--> <!--<i class="material-icons">list</i>-->
@ -153,7 +153,14 @@
<div class=""> <div class="">
<div class="md-list-heading">Number of records</div> <div class="md-list-heading">Number of records</div>
<div class="uk-text-small uk-text-muted">{{ aggr.numberOfRecords | number }}</div> <div class="uk-text-small uk-text-muted">{{ aggr?.numberOfRecords>=0 ? aggr.numberOfRecords : 'NA' }}</div>
</div>
</div>
<div class="uk-margin-small-bottom">
<div class="">
<div class="md-list-heading">Completed Successfully</div>
<div class="uk-text-small uk-text-muted">{{ aggr.completedSuccessfully }}</div>
</div> </div>
</div> </div>

View File

@ -12,12 +12,17 @@ export class AuthGuardService implements CanActivate, CanLoad {
canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if ( this.authenticationService.getIsUserLoggedIn() ) { return true; } if ( this.authenticationService.getIsUserLoggedIn() ) { return true; }
/* If no cookie was found, clear the app's session.
The user may have logged out using another OpenAIRE portal */
sessionStorage.clear();
// Store the attempted URL for redirecting // Store the attempted URL for redirecting
sessionStorage.setItem('state.location', state.url); if (state.url !== '/join') {
/* If no cookie was found, clear the app's session.
The user may have logged out using another OpenAIRE portal */
sessionStorage.clear();
this.authenticationService.redirectUrl = state.url;
sessionStorage.setItem('state.location', state.url);
}
console.log('redirect state: ' + sessionStorage.getItem('state.location'));
// If we decide that in this case we will send the user back to the aai // If we decide that in this case we will send the user back to the aai
// this.authenticationService.redirectUrl = state.url; // this.authenticationService.redirectUrl = state.url;

View File

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment'; import { environment } from '../../environments/environment';
import { deleteCookie, getCookie } from '../domain/utils'; import { deleteCookie, getCookie } from '../domain/utils';
@ -8,8 +8,7 @@ import { BehaviorSubject } from 'rxjs';
@Injectable() @Injectable()
export class AuthenticationService { export class AuthenticationService {
constructor(private route: ActivatedRoute, constructor(private router: Router,
private router: Router,
private http: HttpClient) {} private http: HttpClient) {}
private apiUrl: string = environment.API_ENDPOINT; private apiUrl: string = environment.API_ENDPOINT;
@ -18,8 +17,6 @@ export class AuthenticationService {
// store the URL so we can redirect after logging in // store the URL so we can redirect after logging in
public redirectUrl: string; public redirectUrl: string;
private _storage: Storage = sessionStorage;
private cookie: string = null; private cookie: string = null;
public isLoggedIn_ = new BehaviorSubject(false); public isLoggedIn_ = new BehaviorSubject(false);
@ -33,7 +30,6 @@ export class AuthenticationService {
if (this.redirectUrl) { if (this.redirectUrl) {
const url = this.redirectUrl; const url = this.redirectUrl;
this.redirectUrl = null; this.redirectUrl = null;
console.log('stored location', url);
sessionStorage.setItem('state.location', url); sessionStorage.setItem('state.location', url);
} else { } else {
/*sessionStorage.setItem("state.location", this.router.url);*/ /*sessionStorage.setItem("state.location", this.router.url);*/
@ -108,7 +104,7 @@ export class AuthenticationService {
sessionStorage.removeItem('state.location'); sessionStorage.removeItem('state.location');
console.log(`tried to login - returning to state: ${state}`); console.log(`tried to login - returning to state: ${state}`);
if ( !this.getIsUserLoggedIn() ) { if ( !this.getIsUserLoggedIn() ) {
// console.log('user hasn\'t logged in yet -- going to home'); // console.log('user hasn't logged in yet -- redirecting to home');
this.router.navigate(['/home']); this.router.navigate(['/home']);
} else { } else {
this.router.navigate([state]); this.router.navigate([state]);

View File

@ -23,7 +23,7 @@ export class UsagestatsService {
getReportResponse(page: String, pageSize: String, params: URLSearchParams): Observable<ReportResponseWrapper> { getReportResponse(page: String, pageSize: String, params: URLSearchParams): Observable<ReportResponseWrapper> {
const url = `${this.apiUrl}/sushilite/getReportResults/${page}/${pageSize}?${params}`; const url = `${this.apiUrl}/sushilite/getReportResults/${page}/${pageSize}?${params}`;
console.log(`knocking on: ${url}`); // console.log(`knocking on: ${url}`);
return this.httpClient.get<ReportResponseWrapper>(url, headerOptions); return this.httpClient.get<ReportResponseWrapper>(url, headerOptions);
} }

View File

@ -61,7 +61,7 @@
</div> </div>
<div *ngIf="reposOfUser && reposOfUser.length>0" class="menu_section border_top"> <div *ngIf="reposOfUser && reposOfUser.length>0" class="menu_section border_top">
<div class="sidebar_heading">REPOSITORIES</div> <div class="sidebar_heading">DATASOURCES</div>
<ul> <ul>
<li *ngFor="let repo of visibleReposOfUser" [routerLinkActive]="['current_section']" class=""> <li *ngFor="let repo of visibleReposOfUser" [routerLinkActive]="['current_section']" class="">