diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9b0b3b731198568cdc3c4d0d4ebe93a2d739e059..8ae0af991b63643dd0e49daf61bc5e77c53e98a4 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -10,6 +10,7 @@ import { EditorialisationModule } from './editorialisation/editorialisation.modu import { Angulartics2Module } from 'angulartics2'; import { Angulartics2Piwik } from 'angulartics2/piwik'; import { AuthService } from './core/services'; +import { UserModule } from './user/user.module'; // Function used by APP_INITIALIZER before the app start: init user info / statut (expect a promise) export function loadUser(authService: AuthService) { @@ -31,6 +32,7 @@ export function loadUser(authService: AuthService) { HttpClientModule, CoreModule, EditorialisationModule, + UserModule, AppRoutingModule, Angulartics2Module.forRoot([Angulartics2Piwik]), ], diff --git a/src/app/core/components/index.ts b/src/app/core/components/index.ts index 0e1b080f1769eef2a981eddaf4ed83b916351e68..42d2f9fe9ce1ee4409b93ae50c75f874156f9b18 100644 --- a/src/app/core/components/index.ts +++ b/src/app/core/components/index.ts @@ -7,10 +7,9 @@ import { LoginComponent } from './login/login.component'; import { ContactComponent } from './contact/contact.component'; import { SignUpComponent } from './sign-up/sign-up.component'; import { SideMenuComponent } from './main/side-menu/side-menu.component'; -import { UserServicesComponent } from './user-services/user-services.component'; export { HeaderComponent, MainComponent, FooterComponent, NotificationsComponent, - ErrorComponent, LoginComponent, ContactComponent, SignUpComponent, UserServicesComponent }; + ErrorComponent, LoginComponent, ContactComponent, SignUpComponent }; // tslint:disable-next-line:variable-name export const CoreComponents = [ @@ -23,5 +22,4 @@ export const CoreComponents = [ LoginComponent, SignUpComponent, SideMenuComponent, - UserServicesComponent, ]; diff --git a/src/app/core/components/user-services/user-services.component.html b/src/app/core/components/user-services/user-services.component.html deleted file mode 100644 index cf125925f5c6ea1a9eedab1f3aeb4186dba79b76..0000000000000000000000000000000000000000 --- a/src/app/core/components/user-services/user-services.component.html +++ /dev/null @@ -1,73 +0,0 @@ -<section class="section"> - <h2 i18n="@@userService.listOfService">List of services</h2> - <div> - <i class="fas fa-lock-open lock-open-icon"></i> - <h3 class="is-inline-block" i18n="@@userService.myData">My data</h3> - </div> - - <table class="table"> - <thead> - <tr> - <th i18n="@@userService.name">Name</th> - <th>Status</th> - <th>Service</th> - <th i18n="@@userService.validity">Validity</th> - <th i18n="@@userService.delete">Delete</th> - </tr> - </thead> - <tbody> - <tr *ngFor="let service of userServices"> - <td>{{ service.dataset_name }}</td> - <td>{{ statusesTrad[service.status] ? statusesTrad[service.status] : ''}}</td> - <td>{{ service.ressource }}</td> - <td>{{ service.valid_until ? (service.valid_until | date:'dd/MM/yyyy') : ''}}</td> - <td></td> - </tr> - </tbody> - </table> - - <div> - <div class="requestable-services-table-wrapper"> - <table class="table"> - <thead> - <tr> - <th></th> - <th i18n="@@userService.name">Name</th> - <th>Service</th> - <th i18n="@@userService.add">Add</th> - </tr> - </thead> - <tbody> - <ng-container *ngFor="let service of requestableServices; let index = index"> - <tr> - <td (click)="toogleRow(index)"> - <i class="fas fa-angle-right" *ngIf="!isRowOpened(index); else angleDownTemplate"></i> - <ng-template #angleDownTemplate> - <i class="fas fa-angle-down"></i> - </ng-template> - </td> - <td>{{ service.name }}</td> - <td>all</td> - <td><input type="checkbox" (click)="toogleService(service.id)" [checked]="allModeAreSelected(service.id)"></td> - </tr> - <ng-container *ngIf="isRowOpened(index)"> - <tr *ngFor="let mode of service.modes;"> - <td></td> - <td></td> - <td> - {{ mode.name }} - </td> - <td> - <input type="checkbox" [(ngModel)]="mode.selected"> - </td> - </tr> - </ng-container> - </ng-container> - </tbody> - </table> - </div> - </div> - <button type="button" class="button button-gl" [disabled]="requestedServices.length <= 0" (click)="requestAccess()" i18n="@@userService.sendRequest"> - Send my request - </button> -</section> \ No newline at end of file diff --git a/src/app/core/components/user-services/user-services.component.scss b/src/app/core/components/user-services/user-services.component.scss deleted file mode 100644 index 6d9bd22910bef69ca2a47871f78d55282245cdca..0000000000000000000000000000000000000000 --- a/src/app/core/components/user-services/user-services.component.scss +++ /dev/null @@ -1,13 +0,0 @@ -.lock-open-icon { - margin-right: 0.5rem; -} - -i { - cursor: pointer; -} - -.requestable-services-table-wrapper { - max-height: 50vh; - overflow-y: scroll; - display: inline-block; -} \ No newline at end of file diff --git a/src/app/core/core-routing.module.ts b/src/app/core/core-routing.module.ts index 2ab81728b9128ed5cf036bcf55b571ee1eec5f38..042cf903eadef0ab18808e40243c6d6f77487a9a 100644 --- a/src/app/core/core-routing.module.ts +++ b/src/app/core/core-routing.module.ts @@ -1,8 +1,7 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { AppRoutes } from '../routes'; -import { ErrorComponent, ContactComponent, LoginComponent, SignUpComponent, UserServicesComponent } from './components'; -import { AuthenticatedGuard } from './guards/authenticated.guard'; +import { ErrorComponent, ContactComponent, LoginComponent, SignUpComponent } from './components'; export const routes: Routes = [ { @@ -24,14 +23,6 @@ export const routes: Routes = [ title: AppRoutes.signup.title, }, }, - { - path: AppRoutes.userServices.uri, - component: UserServicesComponent, - data: { - title: AppRoutes.userServices.title, - }, - canActivate: [AuthenticatedGuard], - }, { path: AppRoutes.error.uri, component: ErrorComponent, diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 79f3eefe1d08207fc9b0fb62f68fcb68a38d7e14..7dbcc589cc444bc304b0595d0077568fbd5a6ca5 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -22,7 +22,7 @@ import { CoreGuards } from './guards'; FormsModule, GeosourceModule.forRoot(), ], - declarations: [CoreComponents], + declarations: [...CoreComponents], providers: [ ...CoreServices, ...CoreGuards, diff --git a/src/app/core/models/auth.model.ts b/src/app/core/models/auth.model.ts index c3b13bf4441fc4fc7764d5c074442d80687e7f4b..cd39a5abb04b027f95b3aa58122d99fd9716d2dd 100644 --- a/src/app/core/models/auth.model.ts +++ b/src/app/core/models/auth.model.ts @@ -65,25 +65,3 @@ export class LegacyAccount { this.country = form.country; } } - -export interface IRequestedAccessService { - dataset_id: number; - dataset_name: string; - status: string; - ressource: string; - url_pattern: string; - valid_until: Date; -} - -export interface IRestrictedAccessService { - dataset_id: number; - dataset_name: string; - abstract: string; - service_url: string; -} - -export interface IMode { - id: number; - name: string; - abstract: string; -} diff --git a/src/app/core/services/auth.service.ts b/src/app/core/services/auth.service.ts index 4b77e878da9ed4d6fd83ab993d18c709104062ef..8a425913bcb265edbfaa55b0469f20d6e9711063 100644 --- a/src/app/core/services/auth.service.ts +++ b/src/app/core/services/auth.service.ts @@ -6,7 +6,6 @@ import { map } from 'rxjs/operators'; import { Observable } from 'rxjs'; import { ILoginResponse, User, LegacyAccount } from '../models'; import { environment } from '../../../environments/environment'; -import { IRequestedAccessService, IRestrictedAccessService, IMode } from '../models/auth.model'; @Injectable() export class AuthService { @@ -77,56 +76,4 @@ export class AuthService { get userIsSignedIn() { return this._user != null; } - - getUserServices(): Observable<IRequestedAccessService[]> { - return this._http.get<IRequestedAccessService[]>(`${environment.middlewareLegacyAuth}get_user_service/`).pipe( - map( - (res) => { - return res; - }, - (err) => { - throw err; - }, - ), - ); - } - - getRestrictedAccessService(): Observable<IRestrictedAccessService[]> { - return this._http.get<IRestrictedAccessService[]>(`${environment.middlewareLegacyAuth}get_services`).pipe( - map( - (res) => { - return res; - }, - (err) => { - throw err; - }, - ), - ); - } - - getModes(): Observable<IMode[]> { - return this._http.get<IMode[]>(`${environment.middlewareLegacyAuth}get_modes`).pipe( - map( - (res) => { - return res; - }, - (err) => { - throw err; - }, - ), - ); - } - - requestAccessToService(service) { - return this._http.post<any>(`${environment.middlewareLegacyAuth}add_user_service`, service).pipe( - map( - (res) => { - return res; - }, - (err) => { - throw err; - }, - ), - ); - } } diff --git a/src/app/geosource/components/dataset-detail/dataset-data/dataset-data.component.ts b/src/app/geosource/components/dataset-detail/dataset-data/dataset-data.component.ts index e922eb5fdf188d564ada3c4ab74f91f97357e19d..aba637769ba13cff7110dafb3fa3f5a4227513b7 100644 --- a/src/app/geosource/components/dataset-detail/dataset-data/dataset-data.component.ts +++ b/src/app/geosource/components/dataset-detail/dataset-data/dataset-data.component.ts @@ -50,7 +50,6 @@ export class DatasetDataComponent implements OnInit { this.subscriptions.push( // Subscribe to input changes this.searchInput.valueChanges.pipe(debounceTime(500)).subscribe(() => { - console.log('After debounce'); this.searchChanged(); }), // Subscribe to dataset changes diff --git a/src/app/user/components/index.ts b/src/app/user/components/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..b69b686750f7f660789aaac639d5128de33dd2ff --- /dev/null +++ b/src/app/user/components/index.ts @@ -0,0 +1,7 @@ +import { UserServicesComponent } from '../components/user-services/user-services.component'; +export { UserServicesComponent }; + +// tslint:disable-next-line:variable-name +export const UserComponents = [ + UserServicesComponent, +]; diff --git a/src/app/user/components/user-services/user-services.component.html b/src/app/user/components/user-services/user-services.component.html new file mode 100644 index 0000000000000000000000000000000000000000..8cfaf86fa50ece54e4ce5dcb7baf14f729ed87d8 --- /dev/null +++ b/src/app/user/components/user-services/user-services.component.html @@ -0,0 +1,102 @@ +<section class="section"> + <h2 i18n="@@userService.listOfService">List of services</h2> + <div> + <i class="fas fa-lock-open lock-open-icon"></i> + <h3 class="is-inline-block" i18n="@@userService.myData">My data</h3> + </div> + + <div> + <div class="user-services-table-wrapper"> + <table class="table"> + <thead> + <tr> + <th i18n="@@userService.name">Name</th> + <th>Status</th> + <th>Service</th> + <th i18n="@@userService.validity">Validity</th> + <th i18n="@@userService.delete">Delete</th> + </tr> + </thead> + <tbody> + <tr *ngFor="let service of userServices"> + <td>{{ service.dataset_name }}</td> + <td>{{ statusesTrad[service.status] ? statusesTrad[service.status] : ''}}</td> + <td>{{ service.ressource }}</td> + <td>{{ service.valid_until ? (service.valid_until | date:'dd/MM/yyyy') : ''}}</td> + <td> + </td> + </tr> + </tbody> + </table> + </div> + </div> + + <div> + <i class="fas fa-lock lock-icon"></i> + <h3 class="is-inline-block" i18n="@@userService.otherData">Other available data</h3> + </div> + + + <div class="requestable-services-wrapper"> + <div class="columns is-mobile is-marginless requestable-services-header"> + <div class="column is-offset-1 is-5"> + <span class="column-name" i18n="@@userService.name">Name</span> + </div> + <div class="column is-5"> + <span class="column-name">Service</span> + </div> + <div class="column is-1"> + <span class="column-name" i18n="@@userService.add">Add</span> + </div> + </div> + <div class="requestable-services-content"> + <ng-container *ngFor="let service of requestableServices; let index = index"> + + <div class="columns is-mobile is-marginless"> + <div class="column is-1" (click)="toogleRow(index)"> + <i class="fas fa-angle-right" *ngIf="!isRowOpened(index); else angleDownTemplate"></i> + <ng-template #angleDownTemplate> + <i class="fas fa-angle-down"></i> + </ng-template> + </div> + <div class="column is-5"> + <span>{{ service.name }}</span> + </div> + <div class="column is-5"> + <span class="mode-name">{{ getServiceModes(service) }}</span> + </div> + <div class="column is-1"> + <div class="field"> + <input class="is-checkradio is-small is-danger" [id]="service.id + '_all'" type="checkbox" [name]="service.name + '_all'" + (click)="toogleService(service.id)" [checked]="allModeAreSelected(service.id)" [indeterminate]="isUndeterminated(service.id)"> + <label [for]="service.id + '_all'"></label> + </div> + </div> + </div> + + + <div class="columns is-marginless is-multiline modes-columns" *ngIf="isRowOpened(index)"> + <ng-container *ngFor="let mode of service.modes;"> + <div class="column is-offset-6 is-5 mode-name"> + <span>{{ mode.name }}</span> + </div> + <div class="column is-1 modes-column"> + <div class="field"> + <input class="is-checkradio is-small is-danger" [id]="service.id + '_' + mode.id" type="checkbox" + [name]="service.name + '_' + mode.name" [(ngModel)]="mode.selected"> + <label [for]="service.id + '_' + mode.id"></label> + </div> + </div> + </ng-container> + </div> + </ng-container> + </div> + </div> + <div class="action-button-wrapper"> + <button type="button" class="button button-gl is-outlined" [disabled]="requestedServices.length <= 0" (click)="requestAccess()" + i18n="@@userService.sendRequest"> + Send my request + </button> + </div> + +</section> \ No newline at end of file diff --git a/src/app/user/components/user-services/user-services.component.scss b/src/app/user/components/user-services/user-services.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e7b3258815984f8e8c501ab0fa6889c9bd34abf3 --- /dev/null +++ b/src/app/user/components/user-services/user-services.component.scss @@ -0,0 +1,41 @@ +@import "../../../../scss/variables.scss"; + +.lock-open-icon, .lock-icon { + margin-right: 0.5rem; +} + +i { + cursor: pointer; +} + +.requestable-services-content, .user-services-table-wrapper { + max-height: 400px; + overflow-y: overlay; + background-color: white; + + .columns { + border-bottom: 1px solid #dbdbdb; + } +} + +.requestable-services-header { + background-color: white; + border-bottom: 2px solid #dbdbdb; +} + +.is-checkradio { + display: none; +} + +.column-name { + font-weight: bold; +} + +.columns.modes-columns { + background-color: $light-grey; +} + +.action-button-wrapper { + text-align: right; + margin-top: 1rem; +} \ No newline at end of file diff --git a/src/app/core/components/user-services/user-services.component.spec.ts b/src/app/user/components/user-services/user-services.component.spec.ts similarity index 57% rename from src/app/core/components/user-services/user-services.component.spec.ts rename to src/app/user/components/user-services/user-services.component.spec.ts index 969c17fc901de13e554fc4cca4ab0f77deca5cf3..68b40bfb4ae412fbf6f5be50fba5ed8e41f88d3d 100644 --- a/src/app/core/components/user-services/user-services.component.spec.ts +++ b/src/app/user/components/user-services/user-services.component.spec.ts @@ -1,21 +1,32 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { UserServicesComponent } from './user-services.component'; -import { AuthService } from '../../services'; import { of } from 'rxjs'; +import { UserServicesService } from '../../services'; +import { FormsModule } from '@angular/forms'; +import { NotificationService } from '../../../core/services'; -export class AuthServiceMock { +export class UserServicesServiceMock { constructor() { } - get userIsSignedIn() { - return false; + getUserServices() { + return of(); } - getUserServices() { - return of([]); + getModes() { + return of(); } + getRestrictedAccessService() { + return of(); + } +} + +export class NotificationServiceMock { + + constructor() { } + } describe('UserServicesComponent', () => { @@ -24,11 +35,18 @@ describe('UserServicesComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ + imports: [ + FormsModule, + ], declarations: [UserServicesComponent], providers: [ { - provide: AuthService, - useClass: AuthServiceMock, + provide: UserServicesService, + useClass: UserServicesServiceMock, + }, + { + provide: NotificationService, + useClass: NotificationServiceMock, }, ], }) diff --git a/src/app/core/components/user-services/user-services.component.ts b/src/app/user/components/user-services/user-services.component.ts similarity index 65% rename from src/app/core/components/user-services/user-services.component.ts rename to src/app/user/components/user-services/user-services.component.ts index 7a8941b47c37827ad9e9a33be35aa8365bdd872a..b9e2b165ee05ffe71d9074e6c895e65463d41348 100644 --- a/src/app/core/components/user-services/user-services.component.ts +++ b/src/app/user/components/user-services/user-services.component.ts @@ -1,10 +1,11 @@ import { Component, OnInit } from '@angular/core'; -import { AuthService, NotificationService } from '../../services'; +import { NotificationService } from '../../../core/services'; import { statuses } from '../../../../i18n/user-services/user-services'; -import { IRequestedAccessService, IRestrictedAccessService, IMode } from '../../models/auth.model'; +import { IRequestedAccessService, IRestrictedAccessService, IMode } from '../../models'; import { forkJoin } from 'rxjs'; -import { Notification } from '../../models'; +import { Notification } from '../../../core/models'; import { messages } from '../../../../i18n/notification-messages/notification-messages'; +import { UserServicesService } from '../../services/user-services.service'; @Component({ selector: 'app-user-services', @@ -18,20 +19,23 @@ export class UserServicesComponent implements OnInit { modes: IMode[] = []; statusesTrad = statuses; + // Contains the id of the opened rows openedRow: number[] = []; requestableServices = []; constructor( - private _authService: AuthService, + private _userAccessService: UserServicesService, private _notificationService: NotificationService, ) { } ngOnInit() { forkJoin([ - this._authService.getUserServices(), - this._authService.getModes(), - this._authService.getRestrictedAccessService(), + // Get the list of the requested services by the user + this._userAccessService.getUserServices(), + // Get the list of the different modes (wms, ws...) + this._userAccessService.getModes(), + this._userAccessService.getRestrictedAccessService(), ]).subscribe( (results) => { this.userServices = results[0]; @@ -41,11 +45,15 @@ export class UserServicesComponent implements OnInit { this.initRequestableServices(); }, (err) => { - console.log('Something went wrong', err); + this._notificationService.notify(new Notification({ + type: 'error', + message: `${messages.userServices.initializationError}`, + })); }, ); } + // Associating modes to services and removing service/modes that alreay have been requested initRequestableServices() { this.requestableServices = []; // Iterate over the access restricted services @@ -63,7 +71,11 @@ export class UserServicesComponent implements OnInit { } }); - this.requestableServices.push(temp); + // If already all the mode have been requested then do not display the service in the list + if (temp.modes.length > 0) { + this.requestableServices.push(temp); + } + }); } @@ -122,6 +134,22 @@ export class UserServicesComponent implements OnInit { return res; } + isUndeterminated(serviceId: number) { + let res = false; + + const service = this.requestableServices.find(e => e.id === serviceId); + if (service) { + const unselectedMode = service.modes.find(e => e.selected === false); + const selectedMode = service.modes.find(e => e.selected === true); + + if (unselectedMode && selectedMode) { + res = true; + } + } + + return res; + } + get requestedServices() { return this.requestableServices.filter((e) => { return e.modes.findIndex(m => m.selected === true) !== -1 ? true : false; @@ -131,25 +159,45 @@ export class UserServicesComponent implements OnInit { }); } + getServiceModes(service): string { + let str = ''; + const maxElementDisplayed = 3; + const modes = service['modes'].map(mode => mode.name); + + if (modes.length > maxElementDisplayed) { + str = `${modes.slice(0, 3).join(', ')} ...`; + } else { + str = modes.slice(0, 3).join(', '); + } + + return str; + } + requestAccess() { this.requestedServices.forEach((e) => { - this._authService.requestAccessToService({ id: e.id, modes: e.modes.map(e => e.id) }).subscribe( + this._userAccessService.requestAccessToService({ id: e.id, modes: e.modes.map(e => e.id) }).subscribe( (res) => { this._notificationService.notify(new Notification({ type: 'success', message: `${messages.userServices.addSuccess} ${e.name} (${e.modes.map(e => e.name)})`, })); - this._authService.getUserServices().subscribe( + + // Update the list of the user services + this._userAccessService.getUserServices().subscribe( (res) => { this.userServices = res; + this.openedRow = []; this.initRequestableServices(); }, (err) => { + this._notificationService.notify(new Notification({ + type: 'error', + message: `${messages.userServices.failedToLoadUserServices}`, + })); }, ); }, (err) => { - console.log(err); this._notificationService.notify(new Notification({ type: 'error', message: `${messages.userServices.addFailed} "${e.name}" (${e.modes.map(e => e.name)})`, diff --git a/src/app/user/models/index.ts b/src/app/user/models/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..83f4743adefc7268358602cb81cabbcce41d6019 --- /dev/null +++ b/src/app/user/models/index.ts @@ -0,0 +1,5 @@ +import { IRequestedAccessService, IRestrictedAccessService, IMode } from './user-services.model'; + +export { + IRequestedAccessService, IRestrictedAccessService, IMode, +}; diff --git a/src/app/user/models/user-services.model.ts b/src/app/user/models/user-services.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..9b081b60eea12b91ff29f3fae16110f7d5618a4c --- /dev/null +++ b/src/app/user/models/user-services.model.ts @@ -0,0 +1,22 @@ + +export interface IRequestedAccessService { + dataset_id: number; + dataset_name: string; + status: string; + ressource: string; + url_pattern: string; + valid_until: Date; +} + +export interface IRestrictedAccessService { + dataset_id: number; + dataset_name: string; + abstract: string; + service_url: string; +} + +export interface IMode { + id: number; + name: string; + abstract: string; +} diff --git a/src/app/user/services/index.ts b/src/app/user/services/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..398b7a15acb8483e33601ef944a90d0b8ec2da48 --- /dev/null +++ b/src/app/user/services/index.ts @@ -0,0 +1,8 @@ +import { UserServicesService } from '../services/user-services.service'; + +export { UserServicesService }; + +// tslint:disable-next-line:variable-name +export const UserServices = [ + UserServicesService, +]; diff --git a/src/app/user/services/user-services.service.ts b/src/app/user/services/user-services.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..d79c8193f733ef8409c05318a9ee6455628f9958 --- /dev/null +++ b/src/app/user/services/user-services.service.ts @@ -0,0 +1,66 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { IRequestedAccessService, IRestrictedAccessService, IMode } from '../models'; +import { environment } from '../../../environments/environment'; +import { map } from 'rxjs/operators'; + +@Injectable() +export class UserServicesService { + + constructor( + private _http: HttpClient, + ) { } + + getUserServices(): Observable<IRequestedAccessService[]> { + return this._http.get<IRequestedAccessService[]>(`${environment.middlewareLegacyAuth}get_user_service/`).pipe( + map( + (res) => { + return res; + }, + (err) => { + throw err; + }, + ), + ); + } + + getRestrictedAccessService(): Observable<IRestrictedAccessService[]> { + return this._http.get<IRestrictedAccessService[]>(`${environment.middlewareLegacyAuth}get_services`).pipe( + map( + (res) => { + return res; + }, + (err) => { + throw err; + }, + ), + ); + } + + getModes(): Observable<IMode[]> { + return this._http.get<IMode[]>(`${environment.middlewareLegacyAuth}get_modes`).pipe( + map( + (res) => { + return res; + }, + (err) => { + throw err; + }, + ), + ); + } + + requestAccessToService(service) { + return this._http.post<any>(`${environment.middlewareLegacyAuth}add_user_service`, service).pipe( + map( + (res) => { + return res; + }, + (err) => { + throw err; + }, + ), + ); + } +} diff --git a/src/app/user/user-routing.module.ts b/src/app/user/user-routing.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..b1fb36ebc80bab1e299154568eade31fc1fc8d78 --- /dev/null +++ b/src/app/user/user-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { AppRoutes } from '../routes'; +import { AuthenticatedGuard } from '../core/guards/authenticated.guard'; +import { UserServicesComponent } from './components/user-services/user-services.component'; + +export const routes: Routes = [ + { + path: AppRoutes.userServices.uri, + component: UserServicesComponent, + canActivate: [AuthenticatedGuard], + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class UserRoutingModule { } diff --git a/src/app/user/user.module.ts b/src/app/user/user.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..2d6804b5f4f6803771b4d456a21b8d45405cdb23 --- /dev/null +++ b/src/app/user/user.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { UserRoutingModule } from './user-routing.module'; +import { UserServices } from './services'; +import { UserComponents } from './components'; +import { FormsModule } from '@angular/forms'; + +@NgModule({ + imports: [ + CommonModule, + UserRoutingModule, + FormsModule, + ], + providers: [ + UserServices, + ], + declarations: [...UserComponents], +}) +export class UserModule { } diff --git a/src/i18n/messages.en.xlf b/src/i18n/messages.en.xlf index c5fcccf7d4d6e0b57c392c3cc24e39f4e7df6480..0bde4a94fc7bbf74c02d660b94b658fc8c6880cd 100644 --- a/src/i18n/messages.en.xlf +++ b/src/i18n/messages.en.xlf @@ -577,6 +577,18 @@ <source>Delete</source> <target>Delete</target> </trans-unit> + <trans-unit id="userService.otherData" datatype="html"> + <source>Other available data</source> + <target>Other available data</target> + </trans-unit> + <trans-unit id="userService.add" datatype="html"> + <source>Add</source> + <target>Add</target> + </trans-unit> + <trans-unit id="userService.sendRequest" datatype="html"> + <source>Send my request</source> + <target>Send my request</target> + </trans-unit> </body> </file> </xliff> diff --git a/src/i18n/messages.fr.xlf b/src/i18n/messages.fr.xlf index eb727ab9d8a0888c4d587128d76ce7c05a7ee4a3..0d32436a509d6661f9063c74382150528fc4ff1e 100644 --- a/src/i18n/messages.fr.xlf +++ b/src/i18n/messages.fr.xlf @@ -585,6 +585,18 @@ <source>Delete</source> <target>Supprimer</target> </trans-unit> + <trans-unit id="userService.otherData" datatype="html"> + <source>Other available data</source> + <target>Autres données disponibles</target> + </trans-unit> + <trans-unit id="userService.add" datatype="html"> + <source>Add</source> + <target>Ajouter</target> + </trans-unit> + <trans-unit id="userService.sendRequest" datatype="html"> + <source>Send my request</source> + <target>Envoyer ma demande</target> + </trans-unit> </body> </file> </xliff> diff --git a/src/i18n/notification-messages/notification-messages.fr.ts b/src/i18n/notification-messages/notification-messages.fr.ts index bbef064f2f0d269a77c5b3583d0bc300d0618838..709cd43ad42e892c93e24230e1f329891914ade4 100644 --- a/src/i18n/notification-messages/notification-messages.fr.ts +++ b/src/i18n/notification-messages/notification-messages.fr.ts @@ -34,5 +34,7 @@ export const messages = { userServices: { addSuccess: 'Vous avez demandé l\'accès à', addFailed: 'Une erreur est survenu lors de la demande d\'accès à ', + failedToLoadUserServices: 'Une erreur est survenue lors du chargement de vos données.', + initializationError: 'Une erreur est survenue lors de l\'initialization de la page.', }, }; diff --git a/src/i18n/notification-messages/notification-messages.ts b/src/i18n/notification-messages/notification-messages.ts index ed8ba1e902ffecd5451e2b4f409f6d7511660709..d2f9e7a09f0d14c3695c3f2c19ec6473acba510b 100644 --- a/src/i18n/notification-messages/notification-messages.ts +++ b/src/i18n/notification-messages/notification-messages.ts @@ -33,5 +33,7 @@ export const messages = { userServices: { addSuccess: 'You requested access to ', addFailed: 'An error occured while requesting access to ', + failedToLoadUserServices: 'An error occured while loading your services.', + initializationError: 'An error occured while initializing the page.', }, }; diff --git a/src/styles.scss b/src/styles.scss index a036b3319a79831affcb2a4aadab7c8ba9b7e961..5e746e0d1e978a94108d065e2fa2672f1a5bc75a 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -200,6 +200,12 @@ a:hover { border-color: $red; box-shadow: none; } + + &:disabled { + color: $dark-blue; + background: transparent; + opacity: 0.38; + } } &:disabled {