Skip to content

Commit

Permalink
Merge pull request #2519 from sap-labs-france/master-qa
Browse files Browse the repository at this point in the history
Merge master-qa
  • Loading branch information
LucasBrazi06 authored Jul 30, 2021
2 parents d567219 + 515dc28 commit 1feb537
Show file tree
Hide file tree
Showing 24 changed files with 301 additions and 21 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ev-dashboard",
"description": "Dashboard for Electric Vehicle charging station",
"homepage": "https://github.com/sap-labs-france/ev-dashboard",
"version": "2.4.80",
"version": "2.4.81",
"engines": {
"npm": "6.x.x."
},
Expand Down
2 changes: 2 additions & 0 deletions src/app/authentication/authentication.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { AuthenticationRoutes } from './authentication.routing';
import { AuthenticationDefinePasswordComponent } from './define-password/authentication-define-password.component';
import { AuthenticationEulaComponent } from './eula/authentication-eula.component';
import { AuthenticationLoginComponent } from './login/authentication-login.component';
import { AuthenticationMercedesDataUsageComponent } from './mercedes-data-usage/authentication-mercedes-data-usage.component';
import { AuthenticationRegisterComponent } from './register/authentication-register.component';
import { AuthenticationResetPasswordComponent } from './reset-password/authentication-reset-password.component';
import { AuthenticationVerifyEmailComponent } from './verify-email/authentication-verify-email.component';
Expand All @@ -29,6 +30,7 @@ import { AuthenticationVerifyEmailComponent } from './verify-email/authenticatio
declarations: [
AuthenticationLoginComponent,
AuthenticationEulaComponent,
AuthenticationMercedesDataUsageComponent,
AuthenticationRegisterComponent,
AuthenticationResetPasswordComponent,
AuthenticationDefinePasswordComponent,
Expand Down
8 changes: 7 additions & 1 deletion src/app/authentication/authentication.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Routes } from '@angular/router';
import { AuthenticationDefinePasswordComponent } from './define-password/authentication-define-password.component';
import { AuthenticationEulaComponent } from './eula/authentication-eula.component';
import { AuthenticationLoginComponent } from './login/authentication-login.component';
import { AuthenticationMercedesDataUsageComponent } from './mercedes-data-usage/authentication-mercedes-data-usage.component';
import { AuthenticationRegisterComponent } from './register/authentication-register.component';
import { AuthenticationResetPasswordComponent } from './reset-password/authentication-reset-password.component';
import { AuthenticationVerifyEmailComponent } from './verify-email/authentication-verify-email.component';
Expand All @@ -23,7 +24,12 @@ export const AuthenticationRoutes: Routes = [
}, {
path: 'eula',
component: AuthenticationEulaComponent,
}, {
},
{
path: 'mercedes-data-usage',
component: AuthenticationMercedesDataUsageComponent,
},
{
path: 'verify-email',
component: AuthenticationVerifyEmailComponent,
}, {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="wrapper wrapper-full-page">
<div class="page-header register-page header-filter" filter-color="black">
<div class="container">
<div class="row">
<div class="col-md-12 ml-auto mr-auto mt-5 pt-5 eula-page">
<div>{{"authentication.mercedes_data_usage" | translate}}</div>
</div>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Component, } from '@angular/core';

import { SpinnerService } from '../../services/spinner.service';

@Component({
templateUrl: './authentication-mercedes-data-usage.component.html',
})
export class AuthenticationMercedesDataUsageComponent {

public constructor(
private spinnerService: SpinnerService,
) {
this.spinnerService.hide();
}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { IntegrationConnectionType } from 'types/Connection';

import { CentralServerService } from '../../../../services/central-server.service';
import { MessageService } from '../../../../services/message.service';
Expand All @@ -25,7 +26,7 @@ export class ConcurUserConnectionComponent extends AbstractTabComponent {

if (this.activatedRoute.snapshot.queryParams['state']) {
const state = JSON.parse(this.activatedRoute.snapshot.queryParams['state']);
if (state.connector === 'concur') {
if (state.connector === IntegrationConnectionType.CONCUR) {
this.createConcurConnection(state);
}
}
Expand All @@ -35,7 +36,7 @@ export class ConcurUserConnectionComponent extends AbstractTabComponent {
if (this.activatedRoute.snapshot.queryParams['code']) {
const payload = {
userId: state.userId,
connectorId: 'concur',
connectorId: IntegrationConnectionType.CONCUR,
data:
{
code: this.activatedRoute.snapshot.queryParams['code'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<div class="main-content">
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Component } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { IntegrationConnectionType } from 'types/Connection';

import { CentralServerService } from '../../../../services/central-server.service';
import { MessageService } from '../../../../services/message.service';
import { WindowService } from '../../../../services/window.service';
import { AbstractTabComponent } from '../../../../shared/component/abstract-tab/abstract-tab.component';
import { ActionResponse } from '../../../../types/DataResult';
import { RestResponse } from '../../../../types/GlobalType';
import { Utils } from '../../../../utils/Utils';

@Component({
templateUrl: 'mercedes-user-connection.component.html',
})
export class MercedesUserConnectionComponent extends AbstractTabComponent {

public constructor(
private centralServerService: CentralServerService,
private messageService: MessageService,
private router: Router,
activatedRoute: ActivatedRoute,
windowService: WindowService) {
super(activatedRoute, windowService, [], false);

if (this.activatedRoute.snapshot.queryParams['state']) {
const state = JSON.parse(this.activatedRoute.snapshot.queryParams['state']);
if (state.connector === IntegrationConnectionType.MERCEDES) {
this.createMercedesConnection(state);
}
}
}

private createMercedesConnection(state: any) {
if (this.activatedRoute.snapshot.queryParams['code']) {
const payload = {
userId: state.userId,
connectorId: IntegrationConnectionType.MERCEDES,
data:
{
code: this.activatedRoute.snapshot.queryParams['code'],
redirectUri: this.windowService.getOrigin() + this.windowService.getPath(),
},
};
this.centralServerService.createIntegrationConnection(payload).subscribe((response: ActionResponse) => {
if (response.status === RestResponse.SUCCESS) {
this.messageService.showSuccessMessage('settings.car_connector.mercedes.link_success');
} else {
Utils.handleError(JSON.stringify(response),
this.messageService, 'settings.car_connector.mercedes.link_error');
}
this.router.navigate(['/users/profile'], { fragment: 'connections' });
}, (error) => {
Utils.handleError(JSON.stringify(error),
this.messageService, 'settings.car_connector.mercedes.link_error');
this.router.navigate(['/users/profile'], { fragment: 'connections' });
},
);
} else if (this.activatedRoute.snapshot.queryParams['error']) {
Utils.handleError(this.activatedRoute.snapshot.queryParams['error'],
this.messageService, 'settings.car_connector.mercedes.link_error');
this.router.navigate(['/users/profile'], { fragment: 'connections' });
}
}
}
34 changes: 33 additions & 1 deletion src/app/pages/users/user/user.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,39 @@ <h2 class="card-title">Concur</h2>
</div>
</div>
</div>
<div *ngIf="!refundSetting" class="mx-auto my-3">
<div *ngIf="mercedesConnectionSetting" class="col-md-6 col-xl-4">
<div class="card">
<div class="card-body">
<div class="d-flex flex-row align-items-center">
<img src="/assets/img/integrations/mercedes-logo.png"
class="card-logo img-thumbnail mr-3"/>
<h2 class="card-title">{{'settings.car_connector.types.mercedes' | translate}}</h2>
</div>
</div>
<div class="card-footer">
<div *ngIf="isMercedesUserConnectionValid"
class="d-flex flex-row align-items-center justify-content-between">
<div class="d-flex flex-column align-items-start">
<span>{{'users.connectors.created_on' | translate}} {{ mercedesUserConnection.createdAt | appDate}}</span>
<span>{{'users.connectors.expired_on' | translate}} {{ mercedesUserConnection.validUntil | appDate}}</span>
</div>
<button mat-raised-button color="warn" (click)="revokeMercedesAccount()">
<mat-icon>delete</mat-icon>
<span>{{'users.connectors.revoke' | translate}}</span>
</button>
</div>
<div *ngIf="!isMercedesUserConnectionValid"
class="d-flex flex-row align-items-center justify-content-between">
<span>{{'users.connectors.not_connected' | translate}} </span>
<button mat-raised-button color="primary" (click)="linkMercedesAccount()">
<mat-icon>launch</mat-icon>
<span>{{'users.connectors.connect' | translate}}</span>
</button>
</div>
</div>
</div>
</div>
<div *ngIf="!refundSetting && !mercedesConnectionSetting" class="mx-auto my-3">
<p class="table-no-record-found">{{'general.no_connector_available' | translate}}</p>
</div>
</div>
Expand Down
74 changes: 70 additions & 4 deletions src/app/pages/users/user/user.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import { WindowService } from '../../../services/window.service';
import { AbstractTabComponent } from '../../../shared/component/abstract-tab/abstract-tab.component';
import { USER_STATUSES, UserRoles } from '../../../shared/model/users.model';
import { Address } from '../../../types/Address';
import { IntegrationConnection } from '../../../types/Connection';
import { IntegrationConnection, IntegrationConnectionType } from '../../../types/Connection';
import { ActionResponse } from '../../../types/DataResult';
import { KeyValue, RestResponse } from '../../../types/GlobalType';
import { HTTPError } from '../../../types/HTTPError';
import { PricingSettingsType, RefundSettings } from '../../../types/Setting';
import { CarConnectorConnectionSetting, CarConnectorConnectionType, PricingSettingsType, RefundSettings } from '../../../types/Setting';
import TenantComponents from '../../../types/TenantComponents';
import { User, UserRole, UserStatus } from '../../../types/User';
import { Constants } from '../../../utils/Constants';
Expand Down Expand Up @@ -73,8 +73,10 @@ export class UserComponent extends AbstractTabComponent implements OnInit {
public locale!: AbstractControl;
public address!: Address;
public refundSetting!: RefundSettings;
public mercedesConnectionSetting!: CarConnectorConnectionSetting;
public integrationConnections!: IntegrationConnection[];
public refundConnection!: IntegrationConnection;
public mercedesUserConnection!: IntegrationConnection;
public passwords!: FormGroup;
public password!: AbstractControl;
public repeatPassword!: AbstractControl;
Expand Down Expand Up @@ -104,6 +106,7 @@ export class UserComponent extends AbstractTabComponent implements OnInit {
public sendAdminAccountVerificationNotification!: AbstractControl;
public user!: User;
public isRefundConnectionValid!: boolean;
public isMercedesUserConnectionValid!: boolean;
public canSeeInvoice: boolean;
public isBillingComponentActive: boolean;
public canListPaymentMethods: boolean;
Expand Down Expand Up @@ -296,6 +299,7 @@ export class UserComponent extends AbstractTabComponent implements OnInit {
this.loadUser();
}
this.loadRefundSettings();
this.loadMercedesConnectionSettings();
if (!this.inDialog) {
super.enableRoutingSynchronization();
}
Expand Down Expand Up @@ -636,7 +640,7 @@ export class UserComponent extends AbstractTabComponent implements OnInit {
const concurSetting = this.refundSetting.concur;
const returnedUrl = `${this.windowService.getOrigin()}/users/connections`;
const state = {
connector: 'concur',
connector: IntegrationConnectionType.CONCUR,
appId: this.refundSetting.id,
userId: this.currentUserID,
};
Expand All @@ -652,6 +656,42 @@ export class UserComponent extends AbstractTabComponent implements OnInit {
return null;
}

public revokeMercedesAccount() {
this.centralServerService.deleteIntegrationConnection(this.mercedesUserConnection.id).subscribe(
(response: ActionResponse) => {
if (response.status === RestResponse.SUCCESS) {
this.messageService.showSuccessMessage('settings.car_connector.mercedes.revoke_success');
} else {
Utils.handleError(JSON.stringify(response),
this.messageService, 'settings.car_connector.mercedes.revoke_error');
}
this.loadMercedesConnectionSettings();
}, (error) => {
Utils.handleError(JSON.stringify(error),
this.messageService, 'settings.car_connector.mercedes.revoke_error');
this.loadMercedesConnectionSettings();
}
);
}

public linkMercedesAccount() {
if (!this.mercedesConnectionSetting || !this.mercedesConnectionSetting.mercedesConnection) {
this.messageService.showErrorMessage(
this.translateService.instant('settings.car_connector.mercedes.link_error'));
} else {
// Mercedes
const mercedesSetting = this.mercedesConnectionSetting.mercedesConnection;
const returnedUrl = `${this.windowService.getOrigin()}/users/mercedes-connections`;
const state = {
connector: IntegrationConnectionType.MERCEDES,
appId: this.mercedesConnectionSetting.id,
userId: this.currentUserID,
};
this.document.location.href =
`${mercedesSetting.authenticationUrl}/as/authorization.oauth2?client_id=${mercedesSetting.clientId}&response_type=code&scope=mb:vehicle:mbdata:evstatus offline_access&redirect_uri=${returnedUrl}&state=${JSON.stringify(state)}`;
}
}

public closeDialog(saved: boolean = false) {
if (this.inDialog) {
this.windowService.clearSearch();
Expand All @@ -676,7 +716,7 @@ export class UserComponent extends AbstractTabComponent implements OnInit {
this.isRefundConnectionValid = false;
if (connectionResult && !Utils.isEmptyArray(connectionResult.result)) {
for (const connection of connectionResult.result) {
if (connection.connectorId === 'concur') {
if (connection.connectorId === IntegrationConnectionType.CONCUR) {
this.refundConnection = connection;
this.isRefundConnectionValid =
this.refundConnection &&
Expand All @@ -691,6 +731,32 @@ export class UserComponent extends AbstractTabComponent implements OnInit {
}
}

private loadMercedesConnectionSettings() {
if (this.componentService.isActive(TenantComponents.CAR_CONNECTOR)) {
this.componentService.getCarConnectorSettings().subscribe((carConnectorSettings) => {
this.mercedesConnectionSetting = carConnectorSettings.carConnector.connections.find((connection) =>
connection.type === CarConnectorConnectionType.MERCEDES);
});
if (this.currentUserID) {
this.centralServerService.getIntegrationConnections(this.currentUserID).subscribe((connectionResult) => {
this.mercedesUserConnection = null;
this.isMercedesUserConnectionValid = false;
if (connectionResult && !Utils.isEmptyArray(connectionResult.result)) {
for (const connection of connectionResult.result) {
if (connection.connectorId === IntegrationConnectionType.MERCEDES) {
this.mercedesUserConnection = connection;
this.isMercedesUserConnectionValid =
this.mercedesUserConnection &&
this.mercedesUserConnection.validUntil &&
new Date(this.mercedesUserConnection.validUntil).getTime() > new Date().getTime();
}
}
}
});
}
}
}

private createUser(user: User) {
this.updateUserImage(user);
this.updateUserPassword(user);
Expand Down
2 changes: 2 additions & 0 deletions src/app/pages/users/users.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CommonDirectivesModule } from '../../shared/directives/directives.modul
import { FormattersModule } from '../../shared/formatters/formatters.module';
import { TableModule } from '../../shared/table/table.module';
import { ConcurUserConnectionComponent } from './connections/concur/concur-user-connection.component';
import { MercedesUserConnectionComponent } from './connections/mercedes/mercedes-user-connection.component';
import { AppFormatTagStatusPipe, TagStatusFormatterComponent } from './formatters/tag-status-formatter.component';
import { AppUserRolePipe } from './formatters/user-role.pipe';
import { AppFormatUserStatusPipe, UserStatusFormatterComponent } from './formatters/user-status-formatter.component';
Expand Down Expand Up @@ -62,6 +63,7 @@ import { UserRoutes } from './users.routing';
UserSitesDialogComponent,
UserSitesAdminCheckboxComponent,
ConcurUserConnectionComponent,
MercedesUserConnectionComponent,
AppUserRolePipe,
AppUserStatusPipe,
UserSitesOwnerRadioComponent,
Expand Down
9 changes: 9 additions & 0 deletions src/app/pages/users/users.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Routes } from '@angular/router';
import { RouteGuardService } from '../../guard/route-guard';
import { Action, Entity } from '../../types/Authorization';
import { ConcurUserConnectionComponent } from './connections/concur/concur-user-connection.component';
import { MercedesUserConnectionComponent } from './connections/mercedes/mercedes-user-connection.component';
import { UserComponent } from './user/user.component';
import { UsersComponent } from './users.component';

Expand All @@ -15,6 +16,14 @@ export const UserRoutes: Routes = [
},
},
},
{
path: 'mercedes-connections', component: MercedesUserConnectionComponent, canActivate: [RouteGuardService], data: {
auth: {
entity: Entity.USER,
action: Action.UPDATE,
},
},
},
{
path: 'profile', component: UserComponent, canActivate: [RouteGuardService], data: {
auth: {
Expand Down
Loading

0 comments on commit 1feb537

Please sign in to comment.