Ajout des sources
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http";
|
||||
|
||||
import { HttpTokenInterceptor } from "src/app/core/interceptors";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
HttpClientModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: HttpTokenInterceptor, multi: true }
|
||||
]
|
||||
})
|
||||
export class CoreModule { }
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from './core.module';
|
||||
export * from './interceptors';
|
||||
//export * from './interfaces';
|
||||
export * from './models';
|
||||
export * from './services';
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { JwtService } from '../services';
|
||||
|
||||
export interface headersConfig {
|
||||
'Content-Type': string;
|
||||
'Accept': string;
|
||||
'Authorization'?: string;
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class HttpTokenInterceptor implements HttpInterceptor {
|
||||
constructor(private jwtService: JwtService) { }
|
||||
|
||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||
var config: headersConfig = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
};
|
||||
//Basic cmFtcGV1cjpES3hwMjRQUw==
|
||||
//console.log(req.headers.get('Authorization'));
|
||||
const basic = req.headers.get('Authorization');
|
||||
if (basic == 'Basic cmFtcGV1cjpES3hwMjRQUw==') {
|
||||
config['Authorization'] = `${basic}`;
|
||||
} else {
|
||||
const token = this.jwtService.getToken();
|
||||
if (token) {
|
||||
config['Authorization'] = `Token ${token}`;
|
||||
} else if (environment.use_api_key) {
|
||||
config['Authorization'] = `Api-Key ${environment.api_key}`;
|
||||
}
|
||||
}
|
||||
const request = req.clone({ setHeaders: <any>config });
|
||||
return next.handle(request);
|
||||
/*
|
||||
const headers= new HttpHeaders()
|
||||
.set('Content-Type', 'application/json')
|
||||
.set('Accept', 'application/json');
|
||||
const token = this.jwtService.getToken();
|
||||
if (token) {
|
||||
headers.set('Authorization', `Token ${token}`);
|
||||
} else if (environment.use_api_key) {
|
||||
headers.set('Authorization', `Api-Key ${environment.api_key}`);
|
||||
}
|
||||
const request = req.clone({ setHeaders: headers });
|
||||
return next.handle(request);
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './http.token.interceptor';
|
||||
@@ -0,0 +1,6 @@
|
||||
import { Aeronef } from './aeronef.model';
|
||||
|
||||
export interface AeronefList {
|
||||
aeronefs: Array<Aeronef>,
|
||||
aeronefsCount: number
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Profile } from './profile.model';
|
||||
|
||||
export interface Aeronef {
|
||||
aeronef: string;
|
||||
imat: string;
|
||||
author: Profile;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface AeronefAggregate {
|
||||
_id: {
|
||||
aeronef: string,
|
||||
imat: string
|
||||
},
|
||||
count: number
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
export interface ApplicationListConfig {
|
||||
type: string;
|
||||
filters: ApplicationListFilters;
|
||||
}
|
||||
|
||||
export interface ApplicationListFilters {
|
||||
apikey?: string | undefined;
|
||||
author?: string | undefined;
|
||||
limit?: number | undefined;
|
||||
offset?: number | undefined;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Profile } from './profile.model';
|
||||
|
||||
export interface Application {
|
||||
apikey: string;
|
||||
maskedkey: string;
|
||||
slug: string;
|
||||
title: string;
|
||||
description: string;
|
||||
author: Profile;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface Badge {
|
||||
type: string;
|
||||
name: string;
|
||||
value: number;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Profile } from './profile.model';
|
||||
|
||||
export interface Canopy {
|
||||
canopy: string;
|
||||
taille: number;
|
||||
author: Profile;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface CanopyAggregate {
|
||||
_id: {
|
||||
canopy: string,
|
||||
taille: number
|
||||
},
|
||||
count: number
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface CanopySize {
|
||||
id: string;
|
||||
key: any;
|
||||
value: any;
|
||||
doc?: CanopySizeDoc;
|
||||
}
|
||||
export interface CanopySizeDoc {
|
||||
_id: string;
|
||||
_rev: string;
|
||||
type: string;
|
||||
weight: number;
|
||||
values: [];
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Profile } from './profile.model';
|
||||
|
||||
export interface DropZone {
|
||||
lieu: string;
|
||||
oaci: string;
|
||||
author: Profile;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface DropZoneAggregate {
|
||||
_id: {
|
||||
lieu: string,
|
||||
oaci: string
|
||||
},
|
||||
count: number
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface Errors {
|
||||
errors: {[key: string]: string};
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export * from './aeronef.model';
|
||||
export * from './aeronef-list.model';
|
||||
export * from './application.model';
|
||||
export * from './application-list-config.model';
|
||||
export * from './canopy.model';
|
||||
export * from './canopysize.model';
|
||||
export * from './reducerow.model';
|
||||
export * from './dropzone.model';
|
||||
export * from './errors.model';
|
||||
export * from './jump.model';
|
||||
export * from './jump-list.model';
|
||||
export * from './jump-list-config.model';
|
||||
export * from './profile.model';
|
||||
export * from './user.model';
|
||||
@@ -0,0 +1,24 @@
|
||||
export interface JumpListConfig {
|
||||
type: string;
|
||||
filters: JumpListFilters;
|
||||
}
|
||||
|
||||
export interface JumpListFilters {
|
||||
date?: string;
|
||||
numero?: number;
|
||||
lieu?: string;
|
||||
oaci?: string;
|
||||
aeronef?: string;
|
||||
imat?: string;
|
||||
hauteur?: number;
|
||||
voile?: string;
|
||||
taille?: number;
|
||||
categorie?: string;
|
||||
module?: string;
|
||||
participants?: number;
|
||||
accessoires?: string;
|
||||
zone?: string;
|
||||
author?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Jump } from './jump.model';
|
||||
|
||||
export interface JumpList {
|
||||
jumps: Array<Jump>;
|
||||
jumpsCount: number;
|
||||
}
|
||||
|
||||
export interface JumpViewResults {
|
||||
rows: Array<Jump>;
|
||||
total_rows: number;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Profile } from './profile.model';
|
||||
|
||||
export interface Jump {
|
||||
slug: string;
|
||||
date: string;
|
||||
numero: number,
|
||||
lieu?: string;
|
||||
oaci?: string;
|
||||
aeronef?: string;
|
||||
imat?: string;
|
||||
hauteur?: number,
|
||||
voile?: string;
|
||||
taille?: number,
|
||||
categorie?: string;
|
||||
module?: string;
|
||||
participants?: number,
|
||||
sautants?: Array<string>;
|
||||
programme?: string;
|
||||
accessoires?: string;
|
||||
zone?: string;
|
||||
dossier?: string;
|
||||
video?: string;
|
||||
author: Profile;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface JumpDoc {
|
||||
_id?: string;
|
||||
_rev?: string;
|
||||
type: string;
|
||||
date: string;
|
||||
numero: number,
|
||||
lieu?: string;
|
||||
oaci?: string;
|
||||
aeronef?: string;
|
||||
imat?: string;
|
||||
hauteur?: number,
|
||||
voile?: string;
|
||||
taille?: number,
|
||||
categorie?: string;
|
||||
module?: string;
|
||||
participants?: number,
|
||||
programme?: string;
|
||||
accessoires?: string;
|
||||
zone?: string;
|
||||
dossier?: string;
|
||||
video?: string;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Badge } from './badge.model';
|
||||
|
||||
export interface Menu {
|
||||
state: string;
|
||||
name: string;
|
||||
type: string;
|
||||
icon: string;
|
||||
desc?: string;
|
||||
badge?: Badge[];
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface Profile {
|
||||
username: string;
|
||||
licence?: string;
|
||||
image?: string;
|
||||
bg_image?: string;
|
||||
following: boolean;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface ReduceRow {
|
||||
key: string[];
|
||||
value: number;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
export interface User {
|
||||
email: string;
|
||||
username: string;
|
||||
role: string;
|
||||
firstname: string;
|
||||
lastname: string;
|
||||
phone: string;
|
||||
licence?: number;
|
||||
image?: string;
|
||||
bg_image?: string;
|
||||
token: string;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { Aeronef, AeronefAggregate, AeronefList, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AeronefsService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAll(): Observable<Array<AeronefAggregate>> {
|
||||
return this.apiService.get('/aeronefs')
|
||||
.pipe(map(data => data.aeronefs));
|
||||
/*
|
||||
//return this.apiService.get('/aeronefs');
|
||||
return this.apiService.get('/aeronefs')
|
||||
.pipe(map(data => {
|
||||
return {
|
||||
aeronefs: <Array<Aeronef>>data.aeronefs,
|
||||
aeronefsCount: <number>data.aeronefsCount
|
||||
};
|
||||
}));
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApiService {
|
||||
constructor(
|
||||
private http: HttpClient
|
||||
) { }
|
||||
|
||||
private formatErrors(error: any) {
|
||||
return throwError(error.error);
|
||||
}
|
||||
|
||||
get(path: string, params: HttpParams = new HttpParams()): Observable<any> {
|
||||
return this.http.get(
|
||||
`${environment.api_url}${path}`,
|
||||
{ params }
|
||||
).pipe(catchError(this.formatErrors));
|
||||
}
|
||||
|
||||
put(path: string, body: NonNullable<unknown> = {}): Observable<any> {
|
||||
return this.http.put(
|
||||
`${environment.api_url}${path}`,
|
||||
JSON.stringify(body)
|
||||
).pipe(catchError(this.formatErrors));
|
||||
}
|
||||
|
||||
post(path: string, body: NonNullable<unknown> = {}): Observable<any> {
|
||||
return this.http.post(
|
||||
`${environment.api_url}${path}`,
|
||||
JSON.stringify(body)
|
||||
).pipe(catchError(this.formatErrors));
|
||||
}
|
||||
|
||||
delete(path: string): Observable<any> {
|
||||
return this.http.delete(
|
||||
`${environment.api_url}${path}`
|
||||
).pipe(catchError(this.formatErrors));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { Application, ApplicationListConfig, ApplicationListFilters } from 'src/app/core/models';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApplicationsService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
query(config: ApplicationListConfig): Observable<{ applications: Application[], applicationsCount: number }> {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
const params: ApplicationListFilters = {
|
||||
apikey: config.filters.apikey,
|
||||
author: config.filters.author,
|
||||
limit: config.filters.limit,
|
||||
offset: config.filters.offset
|
||||
};
|
||||
return this.apiService
|
||||
.get(
|
||||
'/applications' + ((config.type === 'feed') ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <any>params })
|
||||
);
|
||||
}
|
||||
|
||||
get(slug: string): Observable<Application> {
|
||||
return this.apiService.get(`/applications/${slug}`)
|
||||
.pipe(map(data => data.application));
|
||||
}
|
||||
|
||||
destroy(slug: string) {
|
||||
return this.apiService.delete(`/applications/${slug}`);
|
||||
}
|
||||
|
||||
save(application: Application): Observable<Application> {
|
||||
if (application.slug) {
|
||||
// If we're updating an existing application
|
||||
return this.apiService.put(`/applications/${application.slug}`, { application: application })
|
||||
.pipe(map(data => data.application));
|
||||
} else {
|
||||
// Otherwise, create a new application
|
||||
return this.apiService.post('/applications/', { application: application })
|
||||
.pipe(map(data => data.application));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { UserService } from 'src/app/core/services';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor(
|
||||
private userService: UserService
|
||||
) { }
|
||||
|
||||
canActivate(
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot
|
||||
): Observable<boolean> {
|
||||
|
||||
return this.userService.isAuthenticated.pipe(take(1));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { UserService } from 'src/app/core/services';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class AuthResolver implements Resolve<boolean> {
|
||||
constructor(
|
||||
private userService: UserService
|
||||
) { }
|
||||
|
||||
resolve(
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot
|
||||
): Observable<boolean> {
|
||||
|
||||
return this.userService.isAuthenticated.pipe(take(1));
|
||||
|
||||
}
|
||||
}
|
||||
Executable
+250
@@ -0,0 +1,250 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { JumpDoc, JumpViewResults } from 'src/app/core/models';
|
||||
import { environment } from 'src/environments/environment';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class BackendService {
|
||||
private _couchdbUrl = environment.couchdbUrl;
|
||||
private _couchdbDatabase = environment.couchdbDatabase;
|
||||
private _couchdbDesign = environment.couchdbDesign;
|
||||
private _couchdbCredential = environment.couchdbCredential;
|
||||
//private _couchdbUrl = "http://couchdb.unespace.com/material_grow/_design/netgrowing_app/_view/allDevices";
|
||||
|
||||
httpOptions = {
|
||||
headers: new HttpHeaders({
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Basic ' + this._couchdbCredential
|
||||
})
|
||||
}
|
||||
|
||||
constructor(private _http: HttpClient) { }
|
||||
|
||||
/* get all docs from couchDB view 'allSolenoids' */
|
||||
getChartColors() {
|
||||
let colors: string[] = [
|
||||
'ct-color-a',
|
||||
'ct-color-b',
|
||||
'ct-color-c',
|
||||
'ct-color-d',
|
||||
'ct-color-e',
|
||||
'ct-color-f',
|
||||
'ct-color-g',
|
||||
'ct-color-h',
|
||||
'ct-color-i',
|
||||
'ct-color-j',
|
||||
'ct-color-k',
|
||||
'ct-color-l',
|
||||
'ct-color-m',
|
||||
'ct-color-n',
|
||||
'ct-color-o',
|
||||
'ct-color-p',
|
||||
'ct-color-q',
|
||||
'ct-color-r'
|
||||
];
|
||||
return colors;
|
||||
}
|
||||
|
||||
writeDoc(doc: Object): Promise<Object | undefined> {
|
||||
const url = this._couchdbUrl + '/' + this._couchdbDatabase;
|
||||
return this._http.post<Object>(url, doc, this.httpOptions).toPromise();
|
||||
}
|
||||
|
||||
updateDoc(doc: JumpDoc): Promise<Object | undefined> {
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/${doc._id}`;
|
||||
return this._http.put<Object>(url, doc, this.httpOptions).toPromise();
|
||||
}
|
||||
|
||||
deleteDoc(id: string, rev: string): Promise<Object | undefined> {
|
||||
//const url = this._couchdbUrl + '/' + this._couchdbDatabase + '/' + id + '?rev=' + rev;
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/${id}?rev=${rev}`;
|
||||
return this._http.delete(url, this.httpOptions).toPromise();
|
||||
}
|
||||
|
||||
/* helper function to save date on updated_at, created_at */
|
||||
getCurrentDate(): Date {
|
||||
return new Date();
|
||||
}
|
||||
|
||||
getCurrentDateFr(): string {
|
||||
return new Date().toLocaleDateString("fr");
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'allJumps' */
|
||||
getJumps(): Observable<JumpViewResults> {
|
||||
//const url = this._couchdbUrl + '/' + this._couchdbDatabase + '/_design/' + this._couchdbDesign + '/_view/allJumps/';
|
||||
//return this._http.get(url, this.httpOptions);
|
||||
const payload = {
|
||||
"include_docs": false,
|
||||
"reduce": false,
|
||||
"descending": false
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/allJumps/`;
|
||||
return this._http.post<JumpViewResults>(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'allJumpsByDate' */
|
||||
getJumpsByDate(level: number): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true,
|
||||
"group_level": level
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/allJumpsByDate/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'filterAeronef' */
|
||||
getAeronefs(): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/filterAeronef/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'filterAeronefByDate' */
|
||||
getAeronefsByDate(level: number): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true,
|
||||
"group_level": level
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/filterAeronefByDate/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'filterCanopyModel' */
|
||||
getCanopyModels(): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/filterCanopyModel/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'filterCanopyModelByDate' */
|
||||
getCanopyModelsByDate(level: number): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true,
|
||||
"group_level": level
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/filterCanopyModelByDate/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'filterCanopySize' */
|
||||
getCanopySizes(): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/filterCanopySize/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'filterCanopySizeByDate' */
|
||||
getCanopySizesByDate(level: number): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true,
|
||||
"group_level": level
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/filterCanopySizeByDate/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'allDropZones' */
|
||||
getDropZones(): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/allDropZones/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'allDropZonesByDate' */
|
||||
getDropZonesByDate(level: number): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true,
|
||||
"group_level": level
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/allDropZonesByDate/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'allJumps' */
|
||||
getTotalJumps(): Observable<Object> {
|
||||
const payload = {
|
||||
"reduce": true,
|
||||
"group": true,
|
||||
"group_level": 1
|
||||
}
|
||||
const url = `${this._couchdbUrl}/${this._couchdbDatabase}/_design/${this._couchdbDesign}/_view/allJumps/`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'allDevices' */
|
||||
getDeviceActivities(deviceId: string, limit: number, start: number, end: number): Observable<Object> {
|
||||
const payload = {
|
||||
"selector": {
|
||||
"type": {
|
||||
"$eq": "activity"
|
||||
},
|
||||
"device_id": {
|
||||
"$eq": deviceId
|
||||
},
|
||||
"created_time": {
|
||||
"$gte": start,
|
||||
"$lte": end
|
||||
}
|
||||
},
|
||||
"fields": [
|
||||
"created_time",
|
||||
"device_id",
|
||||
"values"
|
||||
],
|
||||
"sort": [
|
||||
{
|
||||
"created_time": "desc"
|
||||
}
|
||||
],
|
||||
"limit": limit
|
||||
}
|
||||
//const url = this._couchdbUrl + '/' + this._couchdbDatabase + '/_find';
|
||||
const url = `${this._couchdbUrl}/material_grow/_find`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
/* get all docs from couchDB view 'getDevicesActivities' */
|
||||
getDevicesActivities(key: string, limit: number, start: any, end: any): Observable<Object> {
|
||||
/*
|
||||
const payload = {
|
||||
"start_key": [deviceId, end],
|
||||
"end_key": [deviceId, start],
|
||||
"descending": true,
|
||||
"limit": limit,
|
||||
"reduce": false
|
||||
}
|
||||
const url = this._couchdbUrl + '/' + this._couchdbDatabase + '/_design/' + this._couchdbDesign + '/_view/allActivitiesByDevice/';
|
||||
*/
|
||||
const payload = {
|
||||
"start_key": [key, 1, start],
|
||||
"end_key": [key, 1, end],
|
||||
"limit": limit,
|
||||
"descending": true,
|
||||
"include_docs": true,
|
||||
"reduce": false
|
||||
}
|
||||
const url = `${this._couchdbUrl}/netgrowing/_design/app/_view/getDevicesActivities`;
|
||||
return this._http.post(url, payload, this.httpOptions);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { Canopy, CanopyAggregate ,JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CanopiesService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAll(): Observable<Array<CanopyAggregate>> {
|
||||
return this.apiService.get('/canopies')
|
||||
.pipe(map(data => data.canopies));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { DropZone, DropZoneAggregate, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class DropZonesService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAll(): Observable<Array<DropZoneAggregate>> {
|
||||
return this.apiService.get('/dropzones')
|
||||
.pipe(map(data => data.dropzones));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export * from './api.service';
|
||||
export * from './applications.service';
|
||||
export * from './auth-guard.service';
|
||||
export * from './auth-resolver.service';
|
||||
export * from './backend.service';
|
||||
export * from './aeronefs.service';
|
||||
export * from './canopies.service';
|
||||
export * from './dropzones.service';
|
||||
export * from './jumps.service';
|
||||
export * from './jwt.service';
|
||||
export * from './no-auth-guard.service';
|
||||
export * from './profiles.service';
|
||||
export * from './user.service';
|
||||
@@ -0,0 +1,102 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from './api.service';
|
||||
import { Jump, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class JumpsService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
query(config: JumpListConfig): Observable<JumpList> {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
const params: JumpListFilters = {
|
||||
date: config.filters.date,
|
||||
lieu: config.filters.lieu,
|
||||
oaci: config.filters.oaci,
|
||||
aeronef: config.filters.aeronef,
|
||||
imat: config.filters.imat,
|
||||
hauteur: config.filters.hauteur,
|
||||
voile: config.filters.voile,
|
||||
taille: config.filters.taille,
|
||||
categorie: config.filters.categorie,
|
||||
module: config.filters.module,
|
||||
participants: config.filters.participants,
|
||||
accessoires: config.filters.accessoires,
|
||||
zone: config.filters.zone,
|
||||
author: config.filters.author,
|
||||
limit: config.filters.limit,
|
||||
offset: config.filters.offset
|
||||
};
|
||||
|
||||
return this.apiService
|
||||
.get(
|
||||
'/jumps' + ((config.type === 'feed') ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <any>params })
|
||||
);
|
||||
}
|
||||
|
||||
get(slug: string): Observable<Jump> {
|
||||
return this.apiService.get(`/jumps/${slug}`)
|
||||
.pipe(map(data => data.jump));
|
||||
}
|
||||
|
||||
getAll(): Observable<[Jump]> {
|
||||
return this.apiService.get('/jumps')
|
||||
.pipe(map(data => data.jumps));
|
||||
}
|
||||
|
||||
create(jump: Jump): Observable<Jump> {
|
||||
return this.apiService.post('/jumps/', { jump: jump })
|
||||
.pipe(map(data => data.jump));
|
||||
}
|
||||
|
||||
update(jump: Jump): Observable<Jump> {
|
||||
return this.apiService.put(`/jumps/${jump.slug}`, { jump: jump })
|
||||
.pipe(map(data => data.jump));
|
||||
}
|
||||
|
||||
destroy(slug: string) {
|
||||
return this.apiService.delete(`/jumps/${slug}`);
|
||||
}
|
||||
|
||||
save(jump: Jump): Observable<Jump> {
|
||||
// If we're updating an existing jump
|
||||
if (jump.slug) {
|
||||
return this.apiService.put('/jumps/' + jump.slug, { jump: jump })
|
||||
.pipe(map(data => data.jump));
|
||||
|
||||
// Otherwise, create a new jump
|
||||
} else {
|
||||
return this.apiService.post('/jumps/', { jump: jump })
|
||||
.pipe(map(data => data.jump));
|
||||
}
|
||||
}
|
||||
|
||||
getAeronefs() {
|
||||
/*
|
||||
[
|
||||
{
|
||||
'$match': {
|
||||
'aeronef': 'Pilatus'
|
||||
}
|
||||
}, {
|
||||
'$group': {
|
||||
'_id': {
|
||||
'Aeronef': '$aeronef',
|
||||
'Imat': '$imat'
|
||||
},
|
||||
'count': {
|
||||
'$sum': 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class JwtService {
|
||||
|
||||
getToken(): string {
|
||||
return window.localStorage['jwtToken'];
|
||||
}
|
||||
|
||||
saveToken(token: string) {
|
||||
window.localStorage['jwtToken'] = token;
|
||||
}
|
||||
|
||||
destroyToken() {
|
||||
window.localStorage.removeItem('jwtToken');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { UserService } from 'src/app/core/services';
|
||||
import { map, take } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
//@Injectable({ providedIn: 'root' })
|
||||
export class NoAuthGuard implements CanActivate {
|
||||
constructor(
|
||||
private userService: UserService
|
||||
) { }
|
||||
|
||||
canActivate(
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot
|
||||
): Observable<boolean> {
|
||||
|
||||
return this.userService.isAuthenticated.pipe(take(1), map(isAuth => !isAuth));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { ApiService } from 'src/app/core/services';
|
||||
import { Profile } from 'src/app/core/models';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ProfilesService {
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
get(username: string): Observable<Profile> {
|
||||
return this.apiService.get('/profiles/' + username)
|
||||
.pipe(map((data: { profile: Profile }) => data.profile));
|
||||
}
|
||||
|
||||
follow(username: string): Observable<Profile> {
|
||||
return this.apiService.post('/profiles/' + username + '/follow');
|
||||
}
|
||||
|
||||
unfollow(username: string): Observable<Profile> {
|
||||
return this.apiService.delete('/profiles/' + username + '/follow');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { Observable, BehaviorSubject, ReplaySubject, Subscription } from 'rxjs';
|
||||
import { map, distinctUntilChanged, take } from 'rxjs/operators';
|
||||
|
||||
import { User } from 'src/app/core/models';
|
||||
import { ApiService, JwtService } from 'src/app/core/services';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class UserService implements OnDestroy {
|
||||
private _subcriptions: Array<Subscription> = new Array<Subscription>();
|
||||
private _user: Subscription = new Subscription();
|
||||
private currentUserSubject = new BehaviorSubject<User>({} as User);
|
||||
public currentUser = this.currentUserSubject.asObservable().pipe(distinctUntilChanged());
|
||||
|
||||
private isAuthenticatedSubject = new ReplaySubject<boolean>(1);
|
||||
public isAuthenticated = this.isAuthenticatedSubject.asObservable();
|
||||
|
||||
|
||||
constructor(
|
||||
private apiService: ApiService,
|
||||
private jwtService: JwtService
|
||||
) { }
|
||||
|
||||
ngOnDestroy() {
|
||||
this._subcriptions.forEach((subscription: Subscription) => subscription.unsubscribe());
|
||||
}
|
||||
|
||||
// Verify JWT in localstorage with server & load user's info.
|
||||
// This runs once on application startup.
|
||||
populate() {
|
||||
// If JWT detected, attempt to get & store user's info
|
||||
if (this.jwtService.getToken()) {
|
||||
const user$: Observable<any> = this.apiService.get('/user').pipe(take(1));
|
||||
this._user = user$.subscribe({
|
||||
next: (data) => this.setAuth(data.user),
|
||||
error: () => this.purgeAuth()
|
||||
});
|
||||
this._subcriptions.push(this._user);
|
||||
} else {
|
||||
// Remove any potential remnants of previous auth states
|
||||
this.purgeAuth();
|
||||
}
|
||||
}
|
||||
|
||||
setAuth(user: User) {
|
||||
// Save JWT sent from server in localstorage
|
||||
this.jwtService.saveToken(user.token);
|
||||
// Set current user data into observable
|
||||
this.currentUserSubject.next(user);
|
||||
// Set isAuthenticated to true
|
||||
this.isAuthenticatedSubject.next(true);
|
||||
}
|
||||
|
||||
purgeAuth() {
|
||||
// Remove JWT from localstorage
|
||||
this.jwtService.destroyToken();
|
||||
// Set current user to an empty object
|
||||
this.currentUserSubject.next({} as User);
|
||||
// Set auth status to false
|
||||
this.isAuthenticatedSubject.next(false);
|
||||
}
|
||||
|
||||
attemptAuth(type: string, credentials?: any): Observable<User> {
|
||||
let user$: Observable<any>;
|
||||
if (type === 'authenticate') {
|
||||
user$ = this.apiService.get('/authenticate');
|
||||
} else {
|
||||
const route = (type === 'login') ? '/login' : '';
|
||||
user$ = this.apiService.post(`/users${route}`, { user: credentials });
|
||||
}
|
||||
return user$.pipe(map(
|
||||
(data: any) => {
|
||||
this.setAuth(data.user);
|
||||
return data;
|
||||
}
|
||||
));;
|
||||
}
|
||||
|
||||
getCurrentUser(): User {
|
||||
return this.currentUserSubject.value;
|
||||
}
|
||||
|
||||
canAdministrate(): boolean {
|
||||
return (this.currentUserSubject.value.role == 'Admin') ? true : false;
|
||||
}
|
||||
|
||||
|
||||
// Update the user on the server (email, pass, etc)
|
||||
update(user: any): Observable<User> {
|
||||
return this.apiService
|
||||
.put('/user', { user })
|
||||
.pipe(map(data => {
|
||||
// Update the currentUser observable
|
||||
this.currentUserSubject.next(data.user);
|
||||
return data.user;
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user