API: Use noOptions for parameters
Move config.service to _services/ Rationalise bootstrap and conf (WIP) Fix auth: - Add HTTP interceptor - Bootstrap after login/logout Some cleanups
This commit is contained in:
parent
8593d0b5cd
commit
4eb4c0d0dd
29 changed files with 223 additions and 296 deletions
|
@ -17,7 +17,7 @@
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"lint": "ng lint",
|
"lint": "ng lint",
|
||||||
"e2e": "ng e2e",
|
"e2e": "ng e2e",
|
||||||
"generate-client": "openapi --input http://127.0.0.1:5000/openapi.json --output ./src/app/openapi --client angular --useOptions --useUnionTypes",
|
"generate-client": "openapi --input http://127.0.0.1:5000/openapi.json --output ./src/app/openapi --client angular --useUnionTypes",
|
||||||
"source-map-explorer": "source-map-explorer dist/*.js"
|
"source-map-explorer": "source-map-explorer dist/*.js"
|
||||||
},
|
},
|
||||||
"licenses": [
|
"licenses": [
|
||||||
|
|
24
src/app/_helpers/http.interceptor.ts
Normal file
24
src/app/_helpers/http.interceptor.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HTTP_INTERCEPTORS } from '@angular/common/http'
|
||||||
|
import { Observable } from 'rxjs'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AuthInterceptor implements HttpInterceptor {
|
||||||
|
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
|
const token = localStorage.token
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return next.handle(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
req = req.clone({
|
||||||
|
headers: req.headers.set('Authorization', `Bearer ${token}`),
|
||||||
|
})
|
||||||
|
|
||||||
|
return next.handle(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const httpInterceptorProviders = [
|
||||||
|
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
|
||||||
|
]
|
|
@ -1,16 +1,18 @@
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
|
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http'
|
import { HttpClient, HttpHeaders } from '@angular/common/http'
|
||||||
import { Observable, BehaviorSubject, from, throwError } from 'rxjs'
|
import { Observable, BehaviorSubject, from, throwError, of } from 'rxjs'
|
||||||
import { map, catchError } from 'rxjs/operators'
|
import { map, catchError } from 'rxjs/operators'
|
||||||
|
|
||||||
import { User } from '../_models/user'
|
import { User } from '../_models/user'
|
||||||
import { RoleReadNoUsers } from '../openapi'
|
import { RoleReadNoUsers, ApiService, Token } from '../openapi'
|
||||||
|
import { BootstrapService } from './bootstrap.service'
|
||||||
|
import { ConfigService } from './config.service'
|
||||||
|
|
||||||
interface AuthResponse {
|
// interface AuthResponse {
|
||||||
access_token: string,
|
// access_token: string,
|
||||||
roles: string[]
|
// roles: string[]
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthenticationService {
|
export class AuthenticationService {
|
||||||
|
@ -20,6 +22,9 @@ export class AuthenticationService {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _http: HttpClient,
|
private _http: HttpClient,
|
||||||
|
public api: ApiService,
|
||||||
|
public bootstrapService: BootstrapService,
|
||||||
|
public configService: ConfigService,
|
||||||
) {
|
) {
|
||||||
// set token if saved in local storage
|
// set token if saved in local storage
|
||||||
this.user.next(<User>JSON.parse(localStorage.getItem('user')))
|
this.user.next(<User>JSON.parse(localStorage.getItem('user')))
|
||||||
|
@ -54,43 +59,44 @@ export class AuthenticationService {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
login(userName: string, password: string): Observable<AuthResponse> {
|
login(username: string, password: string): Observable<Token> {
|
||||||
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'})
|
const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'})
|
||||||
var formData: any = new URLSearchParams()
|
// var formData: any = new URLSearchParams()
|
||||||
formData.set('username', userName)
|
// formData.set('username', userName)
|
||||||
formData.set('password', password)
|
// formData.set('password', password)
|
||||||
return this._http.post<AuthResponse>(
|
return this.api.loginForAccessTokenApiTokenPost({
|
||||||
'/api/token', formData, {headers: headers}
|
username: username,
|
||||||
).pipe(map(
|
password: password
|
||||||
(response: AuthResponse) => {
|
}).pipe(map(
|
||||||
// login successful if there's a jwt token in the response
|
token => {
|
||||||
let token = response.access_token
|
localStorage.setItem('token', token.access_token)
|
||||||
if (token) {
|
// store jwt token in local storage to keep user logged in between page refreshes
|
||||||
//const decodedToken = this.helper.decodeToken(token)
|
// localStorage.setItem('user',
|
||||||
// store userName and jwt token in local storage to keep user logged in between page refreshes
|
// JSON.stringify({
|
||||||
localStorage.setItem('user',
|
// userName: username,
|
||||||
JSON.stringify({
|
// token: token,
|
||||||
userName: userName,
|
// roles: response.roles,
|
||||||
token: token,
|
// })
|
||||||
roles: response.roles,
|
// )
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
console.log('TODO: AuthenticationService roles to be set by refreshing bootstrap')
|
this.bootstrapService.get().subscribe(
|
||||||
// this.roles = response.roles
|
bsData => this.configService.setConf(bsData)
|
||||||
|
)
|
||||||
|
return token
|
||||||
|
// this.roles = response.roles
|
||||||
|
|
||||||
// Notify
|
// Notify
|
||||||
this.user.next(new User(userName, token))
|
// this.user.next(new User(userName, token))
|
||||||
|
|
||||||
// return true to indicate successful login
|
// return true to indicate successful login
|
||||||
// return true
|
// return true
|
||||||
} else {
|
// } else {
|
||||||
this.user.next(undefined)
|
// this.user.next(undefined)
|
||||||
this.roles = []
|
// this.roles = []
|
||||||
// return false to indicate failed login
|
// // return false to indicate failed login
|
||||||
// return false
|
// // return false
|
||||||
}
|
// }
|
||||||
return response
|
// return response
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -99,24 +105,32 @@ export class AuthenticationService {
|
||||||
// XXX: not completly safe: the server might be down:
|
// XXX: not completly safe: the server might be down:
|
||||||
// We should actually *check* that the logout response is OK and display message
|
// We should actually *check* that the logout response is OK and display message
|
||||||
// clear token remove user from local storage to log user out
|
// clear token remove user from local storage to log user out
|
||||||
let has_token: boolean = this.user.value && !!this.user.value.token
|
// let has_token: boolean = this.user.value && !!this.user.value.token
|
||||||
localStorage.removeItem('user')
|
const has_token: boolean = !!localStorage.getItem('token')
|
||||||
this.user.next(undefined)
|
// localStorage.removeItem('user')
|
||||||
this.roles = []
|
// this.user.next(undefined)
|
||||||
|
// this.roles = []
|
||||||
|
|
||||||
// Tell server that the user has logged out
|
// Tell server that the user has logged out
|
||||||
if (has_token) {
|
if (has_token) {
|
||||||
this._http.get('/auth/logout').subscribe(response => {})
|
this._http.get('/api/logout').subscribe(response => {})
|
||||||
|
localStorage.removeItem('token')
|
||||||
}
|
}
|
||||||
|
this.bootstrapService.get().subscribe(
|
||||||
|
bsData => this.configService.setConf(bsData)
|
||||||
|
)
|
||||||
return has_token
|
return has_token
|
||||||
}
|
}
|
||||||
|
|
||||||
logoutAdmin(): void {
|
logoutAdmin(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
isAuthorized(roles: string[]) {
|
isAuthorized(roles: string[]): Observable<boolean> {
|
||||||
// Return true if at least one role in given list matches one role of the authenticated user
|
// Return true if at least one role in given list matches one role of the authenticated user
|
||||||
if (roles.length == 0) return true
|
if (roles.length == 0) return of(true)
|
||||||
return this.roles.filter(value => -1 !== roles.indexOf(value.name)).length > 0
|
// return this.roles.filter(value => -1 !== roles.indexOf(value.name)).length > 0
|
||||||
|
return this.configService.conf.pipe(map(
|
||||||
|
conf => conf.bsData?.user.roles.filter(value => -1 !== roles.indexOf(value.name)).length > 0
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { Observable } from 'rxjs'
|
import { Observable, map } from 'rxjs'
|
||||||
|
|
||||||
import { ApiService, BootstrapData } from '../openapi'
|
import { ApiService, BootstrapData } from '../openapi'
|
||||||
|
|
||||||
|
|
|
@ -2,23 +2,25 @@ import { inject, Injectable } from "@angular/core"
|
||||||
import { ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot } from "@angular/router"
|
import { ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot } from "@angular/router"
|
||||||
import { Subject, ReplaySubject, BehaviorSubject, Observable, map } from "rxjs"
|
import { Subject, ReplaySubject, BehaviorSubject, Observable, map } from "rxjs"
|
||||||
|
|
||||||
|
import { BootstrapData } from "../openapi"
|
||||||
|
import { BootstrapService } from "./bootstrap.service"
|
||||||
|
|
||||||
export class Config {
|
export class Config {
|
||||||
map = {}
|
constructor(
|
||||||
proj = {}
|
public bsData?: BootstrapData
|
||||||
measures = {}
|
) {}
|
||||||
geo = {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class ConfigService {
|
export class ConfigService {
|
||||||
defaultConf: Config = {
|
// defaultConf: Config = {
|
||||||
'map': {},
|
// 'map': {},
|
||||||
'proj': {},
|
// 'proj': {},
|
||||||
'measures': {},
|
// 'measures': {},
|
||||||
'geo': {}
|
// 'geo': {}
|
||||||
}
|
// }
|
||||||
|
|
||||||
hasConf = new ReplaySubject<undefined>()
|
hasConf = new ReplaySubject<undefined>()
|
||||||
public conf: BehaviorSubject<Config> = new BehaviorSubject<Config>(new Config())
|
public conf: BehaviorSubject<Config> = new BehaviorSubject<Config>(new Config())
|
||||||
|
@ -36,12 +38,14 @@ export class ConfigService {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setConf(c: Object) {
|
setConf(bsData: BootstrapData) {
|
||||||
this.conf.value.map = c['map']
|
this.conf.next(new Config(bsData))
|
||||||
this.conf.value.proj = c['proj']
|
// this.conf.value.map = c.
|
||||||
this.conf.value.geo = c['geo']
|
// this.conf.value.proj = c['proj']
|
||||||
this.conf.value.measures = c['measures']
|
// this.conf.value.geo = c['geo']
|
||||||
this.conf.next(this.conf.value)
|
// this.conf.value.measures = c['measures']
|
||||||
|
// this.conf.next(this.conf.value)
|
||||||
|
localStorage.setItem('bsData', JSON.stringify(bsData))
|
||||||
this.hasConf.next(undefined)
|
this.hasConf.next(undefined)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,7 +36,7 @@ export class DataService {
|
||||||
}
|
}
|
||||||
|
|
||||||
getList(store: string): Observable<MeasuresItem[]> {
|
getList(store: string): Observable<MeasuresItem[]> {
|
||||||
return this.api.getModelListApiDataProviderStoreGet({store: store})
|
return this.api.getModelListApiDataProviderStoreGet(store)
|
||||||
}
|
}
|
||||||
|
|
||||||
getValues(
|
getValues(
|
||||||
|
@ -61,11 +61,8 @@ export class DataService {
|
||||||
// .set('resample', sampling)
|
// .set('resample', sampling)
|
||||||
// .set('format', format)
|
// .set('format', format)
|
||||||
// FIXME: add the name of the value to fetch
|
// FIXME: add the name of the value to fetch
|
||||||
return this.api.getModelValuesApiStoreNameValuesValueGet({
|
return this.api.getModelValuesApiStoreNameValuesValueGet(
|
||||||
storeName: store,
|
store, value, JSON.stringify(p), sampling
|
||||||
value: value,
|
)
|
||||||
where: JSON.stringify(p),
|
|
||||||
resample: sampling
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,7 @@ export class GeoJsonService {
|
||||||
}
|
}
|
||||||
|
|
||||||
getStyle(store: string): Observable<MaplibreStyle> {
|
getStyle(store: string): Observable<MaplibreStyle> {
|
||||||
return this.mapService.getLayerStyleApiMapLayerStyleStoreGet(
|
return this.mapService.getLayerStyleApiMapLayerStyleStoreGet(store)
|
||||||
{store: store}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getAll(url: string, store: string, params?: object): Observable<MapboxDataAndStyle> {
|
getAll(url: string, store: string, params?: object): Observable<MapboxDataAndStyle> {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { RouterModule, Routes } from '@angular/router'
|
import { RouterModule, Routes } from '@angular/router'
|
||||||
import { configResolver } from './config.service'
|
import { configResolver } from './_services/config.service'
|
||||||
import { LoginComponent } from './login/login.component'
|
import { LoginComponent } from './login/login.component'
|
||||||
import { PageNotFoundComponent } from './pageNotFound.component'
|
import { PageNotFoundComponent } from './pageNotFound.component'
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<mat-toolbar fxFlex="2em" id='top-toolbar'>
|
<mat-toolbar fxFlex="2em" id='top-toolbar'>
|
||||||
<span
|
<span
|
||||||
style='font-family:GisafSymbols'
|
style='font-family:GisafSymbols'
|
||||||
matTooltip="Gisaf v. {{ version }}"
|
matTooltip="Gisaf v. {{ (configService.conf | async).bsData?.version }}"
|
||||||
matTooltipPosition="below"
|
matTooltipPosition="below"
|
||||||
class='gisafIcon'
|
class='gisafIcon'
|
||||||
>
|
>
|
||||||
|
@ -25,12 +25,12 @@
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
<span *ngIf="authenticationService.user$ | async; else login" class="auth-indicator">
|
<span *ngIf="(configService.conf | async).bsData?.user; else login" class="auth-indicator">
|
||||||
<nav>
|
<nav>
|
||||||
<a mat-icon-button
|
<a mat-icon-button
|
||||||
(click)='this.authenticationService.logout()'
|
(click)='this.authenticationService.logout()'
|
||||||
aria-label="Log out"
|
aria-label="Log out"
|
||||||
matTooltip="User: {{ (authenticationService.user$ | async ).userName }}. Click to log out">
|
matTooltip="User: {{ (configService.conf | async ).bsData?.user.username }}. Click to log out">
|
||||||
<mat-icon>verified_user</mat-icon>
|
<mat-icon>verified_user</mat-icon>
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Component, OnInit,
|
||||||
ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'
|
ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core'
|
||||||
import { Title } from '@angular/platform-browser'
|
import { Title } from '@angular/platform-browser'
|
||||||
import { BootstrapService } from './_services/bootstrap.service'
|
import { BootstrapService } from './_services/bootstrap.service'
|
||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './_services/config.service'
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar'
|
import { MatSnackBar } from '@angular/material/snack-bar'
|
||||||
|
|
||||||
import { AuthenticationService } from './_services/authentication.service'
|
import { AuthenticationService } from './_services/authentication.service'
|
||||||
|
@ -52,7 +52,6 @@ export class AppComponent implements OnInit {
|
||||||
this.title = res.title || this.title
|
this.title = res.title || this.title
|
||||||
this.titleService.setTitle(res.windowTitle || this.title)
|
this.titleService.setTitle(res.windowTitle || this.title)
|
||||||
this.configService.setConf(res)
|
this.configService.setConf(res)
|
||||||
this.authenticationService.roles = res.user?.roles || []
|
|
||||||
if (res.redirect && (window != window.top)) {
|
if (res.redirect && (window != window.top)) {
|
||||||
// Refusing to be embedded in an iframe
|
// Refusing to be embedded in an iframe
|
||||||
let loc = res.redirect + window.location.pathname
|
let loc = res.redirect + window.location.pathname
|
||||||
|
@ -69,10 +68,5 @@ export class AppComponent implements OnInit {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.authenticationService.isLoggedIn().subscribe({
|
|
||||||
next: resp => resp,
|
|
||||||
error: (err: string) => this.snackBar.open(err, 'OK', {duration: 3000})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,17 @@
|
||||||
import { BrowserModule } from '@angular/platform-browser'
|
import { BrowserModule } from '@angular/platform-browser'
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
||||||
import { Injector, NgModule, LOCALE_ID } from '@angular/core'
|
import { NgModule, LOCALE_ID } from '@angular/core'
|
||||||
import { FormsModule } from '@angular/forms'
|
import { FormsModule } from '@angular/forms'
|
||||||
import { HttpClientModule } from '@angular/common/http'
|
import { HttpClientModule } from '@angular/common/http'
|
||||||
|
|
||||||
import { MatButtonModule } from '@angular/material/button'
|
import { MatButtonModule } from '@angular/material/button'
|
||||||
import { MatIconModule } from '@angular/material/icon'
|
import { MatIconModule } from '@angular/material/icon'
|
||||||
import { MatSnackBarModule } from '@angular/material/snack-bar'
|
import { MatSnackBarModule } from '@angular/material/snack-bar'
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar'
|
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar'
|
import { MatToolbarModule } from '@angular/material/toolbar'
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip'
|
import { MatTooltipModule } from '@angular/material/tooltip'
|
||||||
|
|
||||||
import { FlexLayoutModule } from 'ngx-flexible-layout'
|
import { FlexLayoutModule } from 'ngx-flexible-layout'
|
||||||
|
|
||||||
// import { ApolloModule, APOLLO_OPTIONS } from 'apollo-angular'
|
|
||||||
// import { HttpLink } from 'apollo-angular/http'
|
|
||||||
// import { onError } from '@apollo/client/link/error'
|
|
||||||
// import { split, from, ApolloLink, InMemoryCache, ApolloClientOptions } from '@apollo/client/core'
|
|
||||||
// import { WebSocketLink } from '@apollo/client/link/ws'
|
|
||||||
// import { getMainDefinition, getOperationName } from '@apollo/client/utilities'
|
|
||||||
// import { DefinitionNode } from 'graphql'
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component'
|
import { AppComponent } from './app.component'
|
||||||
import { PageNotFoundComponent } from './pageNotFound.component'
|
import { PageNotFoundComponent } from './pageNotFound.component'
|
||||||
import { LoginModule } from './login/login.module'
|
import { LoginModule } from './login/login.module'
|
||||||
|
@ -28,18 +19,18 @@ import { AuthenticationService } from './_services/authentication.service'
|
||||||
import { BootstrapService } from './_services/bootstrap.service'
|
import { BootstrapService } from './_services/bootstrap.service'
|
||||||
import { ModelDataService } from './_services/apollo.service'
|
import { ModelDataService } from './_services/apollo.service'
|
||||||
import { ActionsService } from './_services/actions.service'
|
import { ActionsService } from './_services/actions.service'
|
||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './_services/config.service'
|
||||||
|
|
||||||
import { ApiService } from './openapi/services/ApiService'
|
import { ApiService } from './openapi/services/ApiService'
|
||||||
import { AdminService } from './openapi/services/AdminService'
|
import { AdminService } from './openapi/services/AdminService'
|
||||||
import { DashboardService } from './openapi/services/DashboardService'
|
import { DashboardService } from './openapi/services/DashboardService'
|
||||||
import { GeoapiService } from './openapi/services/GeoapiService'
|
import { GeoapiService } from './openapi/services/GeoapiService'
|
||||||
import { MapService } from './openapi/services/MapService'
|
import { MapService } from './openapi/services/MapService'
|
||||||
|
import { httpInterceptorProviders } from './_helpers/http.interceptor'
|
||||||
|
|
||||||
import { HtmlSnackbarComponent } from './custom-snackbar/custom-snackbar.component'
|
import { HtmlSnackbarComponent } from './custom-snackbar/custom-snackbar.component'
|
||||||
|
|
||||||
import { AppRoutingModule } from './app-routing.module'
|
import { AppRoutingModule } from './app-routing.module'
|
||||||
import { environment } from '../environments/environment'
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -79,95 +70,11 @@ import { environment } from '../environments/environment'
|
||||||
MapService,
|
MapService,
|
||||||
ConfigService,
|
ConfigService,
|
||||||
ModelDataService,
|
ModelDataService,
|
||||||
|
httpInterceptorProviders,
|
||||||
{
|
{
|
||||||
provide: LOCALE_ID,
|
provide: LOCALE_ID,
|
||||||
useValue: "en-IN"
|
useValue: "en-IN"
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// provide: APOLLO_OPTIONS,
|
|
||||||
// useFactory(httpLink: HttpLink, snackBar: MatSnackBar) {
|
|
||||||
// const definitionIsMutation = (d: DefinitionNode) => {
|
|
||||||
// return d.kind === 'OperationDefinition' && d.operation === 'mutation'
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // See https://github.com/apollographql/apollo-angular/issues/1013
|
|
||||||
// const linkQueries = httpLink.create({
|
|
||||||
// uri: '/graphql',
|
|
||||||
// method: 'GET',
|
|
||||||
// })
|
|
||||||
|
|
||||||
// const linkMutations = httpLink.create({
|
|
||||||
// uri: '/graphql',
|
|
||||||
// })
|
|
||||||
|
|
||||||
// const splittedLink = split(
|
|
||||||
// ({ query }) => query.definitions.some(definitionIsMutation),
|
|
||||||
// linkMutations,
|
|
||||||
// linkQueries,
|
|
||||||
// )
|
|
||||||
|
|
||||||
// const schedulerQueriesLink = httpLink.create({
|
|
||||||
// uri: '/graphql_sched',
|
|
||||||
// method: 'GET',
|
|
||||||
// })
|
|
||||||
|
|
||||||
// const proxyLink = split(
|
|
||||||
// ({ query }) => {
|
|
||||||
// let res = query.definitions[0]['name']['value'].startsWith('scheduler_')
|
|
||||||
// return res
|
|
||||||
// },
|
|
||||||
// schedulerQueriesLink,
|
|
||||||
// splittedLink
|
|
||||||
// )
|
|
||||||
|
|
||||||
// const errorLink = onError(({ graphQLErrors, networkError }) => {
|
|
||||||
// if (graphQLErrors)
|
|
||||||
// graphQLErrors.map(({ message, locations, path }) => {
|
|
||||||
// snackBar.open(`Error: ${message}`, 'close')
|
|
||||||
// console.error(
|
|
||||||
// `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
|
|
||||||
// graphQLErrors
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// if (networkError) {
|
|
||||||
// snackBar.open(
|
|
||||||
// `Network error: ${networkError['statusText']}`,
|
|
||||||
// 'close',
|
|
||||||
// )
|
|
||||||
// console.error(networkError)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// const httpLinkWithErrorHandling = from([
|
|
||||||
// errorLink,
|
|
||||||
// proxyLink,
|
|
||||||
// ])
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// link: httpLinkWithErrorHandling,
|
|
||||||
// cache: new InMemoryCache(),
|
|
||||||
// defaultOptions: {
|
|
||||||
// watchQuery: {
|
|
||||||
// fetchPolicy: 'network-only',
|
|
||||||
// errorPolicy: 'ignore',
|
|
||||||
// },
|
|
||||||
// query: {
|
|
||||||
// fetchPolicy: 'network-only',
|
|
||||||
// errorPolicy: 'all',
|
|
||||||
// },
|
|
||||||
// subscription: {
|
|
||||||
// fetchPolicy: 'network-only',
|
|
||||||
// errorPolicy: 'all',
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// deps: [
|
|
||||||
// HttpLink,
|
|
||||||
// MatSnackBar
|
|
||||||
// ],
|
|
||||||
// }
|
|
||||||
],
|
],
|
||||||
bootstrap: [
|
bootstrap: [
|
||||||
AppComponent
|
AppComponent
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { MapControlService } from '../map/map-control.service'
|
||||||
import { LayerNode } from '../map/models'
|
import { LayerNode } from '../map/models'
|
||||||
import { Tag, TagAction } from './info-tags/tags.service'
|
import { Tag, TagAction } from './info-tags/tags.service'
|
||||||
|
|
||||||
import { ConfigService } from '../config.service'
|
import { ConfigService } from '../_services/config.service'
|
||||||
import { DataService } from '../_services/data.service'
|
import { DataService } from '../_services/data.service'
|
||||||
import { ApiService, ModelInfo, FeatureInfo, PlotParams } from '../openapi'
|
import { ApiService, ModelInfo, FeatureInfo, PlotParams } from '../openapi'
|
||||||
|
|
||||||
|
@ -466,7 +466,7 @@ export class InfoDataService {
|
||||||
public taggedLayers$ = this.taggedLayers.asObservable()
|
public taggedLayers$ = this.taggedLayers.asObservable()
|
||||||
|
|
||||||
getModelInfo(store: string): Observable<ModelInfo> {
|
getModelInfo(store: string): Observable<ModelInfo> {
|
||||||
return this.api.getModelInfoApiModelInfoStoreGet({store: store})
|
return this.api.getModelInfoApiModelInfoStoreGet(store)
|
||||||
console.warn('Migrate Graphql')
|
console.warn('Migrate Graphql')
|
||||||
return observableOf()
|
return observableOf()
|
||||||
// return this.apollo.query({
|
// return this.apollo.query({
|
||||||
|
@ -555,11 +555,7 @@ export class InfoDataService {
|
||||||
}
|
}
|
||||||
|
|
||||||
getPlotParams(store: string, id: string, value: string): Observable<PlotParams> {
|
getPlotParams(store: string, id: string, value: string): Observable<PlotParams> {
|
||||||
return this.api.getPlotParamsApiPlotParamsStoreGet({
|
return this.api.getPlotParamsApiPlotParamsStoreGet(store, id, value)
|
||||||
'store': store,
|
|
||||||
'id': id,
|
|
||||||
'value': value
|
|
||||||
})
|
|
||||||
console.warn('Migrate Graphql')
|
console.warn('Migrate Graphql')
|
||||||
return observableOf()
|
return observableOf()
|
||||||
// return this.apollo.query({
|
// return this.apollo.query({
|
||||||
|
@ -592,10 +588,7 @@ export class InfoDataService {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFeatureInfo(store: string, id: string): Observable<FeatureInfo> {
|
getFeatureInfo(store: string, id: string): Observable<FeatureInfo> {
|
||||||
return this.api.getFeatureInfoApiFeatureInfoStoreIdGet({
|
return this.api.getFeatureInfoApiFeatureInfoStoreIdGet(store, id)
|
||||||
store: store,
|
|
||||||
id: id
|
|
||||||
})
|
|
||||||
// return this.apollo.query({
|
// return this.apollo.query({
|
||||||
// query: getFeatureInfoQuery,
|
// query: getFeatureInfoQuery,
|
||||||
// variables: {
|
// variables: {
|
||||||
|
@ -710,7 +703,7 @@ export class InfoDataService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTagKeys(): Observable<string[]> {
|
public getTagKeys(): Observable<string[]> {
|
||||||
return observableOf(this.configService.conf.value.map['tagKeys'])
|
return observableOf(this.configService.conf.value.bsData?.map['tagKeys'])
|
||||||
// This could be fetched from the server
|
// This could be fetched from the server
|
||||||
/*
|
/*
|
||||||
return this.apollo.query({
|
return this.apollo.query({
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { Router } from '@angular/router'
|
||||||
|
|
||||||
import { UntypedFormGroup, UntypedFormControl, Validators } from '@angular/forms'
|
import { UntypedFormGroup, UntypedFormControl, Validators } from '@angular/forms'
|
||||||
|
|
||||||
import { ConfigService } from '../config.service'
|
import { ConfigService } from '../_services/config.service'
|
||||||
import { AuthenticationService } from '../_services/authentication.service'
|
import { AuthenticationService } from '../_services/authentication.service'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -41,15 +41,8 @@ export class LoginComponent implements OnInit {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.authenticationService.login(this.formGroup.value.userName, this.formGroup.value.password).subscribe({
|
this.authenticationService.login(this.formGroup.value.userName, this.formGroup.value.password).subscribe({
|
||||||
next: result => {
|
next: result => {
|
||||||
if (result.access_token) {
|
// login successful
|
||||||
// login successful
|
this.router.navigate(['/'])
|
||||||
this.router.navigate(['/'])
|
|
||||||
} else {
|
|
||||||
// login failed
|
|
||||||
this.error = 'User name or password is incorrect'
|
|
||||||
this.loading = false
|
|
||||||
this.cdr.markForCheck()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
error: error => {
|
error: error => {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
step=0.01
|
step=0.01
|
||||||
matTooltip="Opacity of the background layer"
|
matTooltip="Opacity of the background layer"
|
||||||
matTooltipPosition="right"
|
matTooltipPosition="right"
|
||||||
#ngSlider><input matSliderThumb value="{{ (configService.conf | async).map['opacity'] }}" (input)="mapControlService.baseStyleOpacity.next({source: ngSliderThumb, parent: ngSlider, value: ngSliderThumb.value}.value)" #ngSliderThumb="matSliderThumb" />
|
#ngSlider><input matSliderThumb value="{{ (configService.conf | async).bsData.map.opacity }}" (input)="mapControlService.baseStyleOpacity.next({source: ngSliderThumb, parent: ngSlider, value: ngSliderThumb.value}.value)" #ngSliderThumb="matSliderThumb" />
|
||||||
</mat-slider>
|
</mat-slider>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
matTooltip='Filter features from survey categories by status'
|
matTooltip='Filter features from survey categories by status'
|
||||||
matTooltipPosition="right"
|
matTooltipPosition="right"
|
||||||
>
|
>
|
||||||
<mat-option *ngFor="let _status of (configService.conf | async).map['status']" [value]="_status">{{ _status }}</mat-option>
|
<mat-option *ngFor="let _status of (configService.conf | async).bsData?.map.status" [value]="_status">{{ _status }}</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
@ -147,22 +147,22 @@
|
||||||
<mat-menu #toolsMenu="matMenu" class='extended-width'>
|
<mat-menu #toolsMenu="matMenu" class='extended-width'>
|
||||||
<button mat-menu-item
|
<button mat-menu-item
|
||||||
(click)="downloadSelectedLayers('gpkg')">
|
(click)="downloadSelectedLayers('gpkg')">
|
||||||
Download Geopackage of selected layers (EPSG {{ (configService.conf | async).geo['srid'] }})
|
Download Geopackage of selected layers (EPSG {{ (configService.conf | async).bsData?.geo.srid }})
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item [disabled]=true
|
<button mat-menu-item [disabled]=true
|
||||||
(click)="downloadSelectedLayers('dxf')">
|
(click)="downloadSelectedLayers('dxf')">
|
||||||
Download DXF of selected layers (EPSG {{ (configService.conf | async).geo['srid'] }})
|
Download DXF of selected layers (EPSG {{ (configService.conf | async).bsData?.geo.srid }})
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item [disabled]=true
|
<button mat-menu-item [disabled]=true
|
||||||
(click)="downloadSelectedLayers('dxf', true)">
|
(click)="downloadSelectedLayers('dxf', true)">
|
||||||
Download DXF of selected layers (reprojected to EPSG {{ (configService.conf | async).geo['srid_for_proj'] }})
|
Download DXF of selected layers (reprojected to EPSG {{ (configService.conf | async).bsData?.geo.srid_for_proj }})
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item
|
<button mat-menu-item
|
||||||
(click)="downloadSelectedLayers('shapefile')">
|
(click)="downloadSelectedLayers('shapefile')">
|
||||||
Download Shapefiles of selected layers (EPSG {{ (configService.conf | async).geo['srid'] }}) [<i><b>Deprecated</b>: use Geopackage</i>]
|
Download Shapefiles of selected layers (EPSG {{ (configService.conf | async).bsData?.geo.srid }}) [<i><b>Deprecated</b>: use Geopackage</i>]
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
<button mat-raised-button [disabled]="!canCreateBaseMap"
|
<button mat-raised-button [disabled]="!(authenticationService.isAuthorized(['base_map_creator']) | async)"
|
||||||
matTooltip="Create a base map with the selected layers"
|
matTooltip="Create a base map with the selected layers"
|
||||||
(click)="createBaseMap()">
|
(click)="createBaseMap()">
|
||||||
Create a base map...
|
Create a base map...
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Component, OnInit } from '@angular/core'
|
||||||
import { FormControl } from '@angular/forms'
|
import { FormControl } from '@angular/forms'
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar'
|
import { MatSnackBar } from '@angular/material/snack-bar'
|
||||||
|
|
||||||
import { ConfigService } from '../../config.service'
|
import { ConfigService } from '../../_services/config.service'
|
||||||
import { MapControlService } from '../map-control.service'
|
import { MapControlService } from '../map-control.service'
|
||||||
import { TreeLayerItemComponent } from '../tree-layer-item/tree-layer-item.component'
|
import { TreeLayerItemComponent } from '../tree-layer-item/tree-layer-item.component'
|
||||||
import { InfoDataService, TaggedLayer } from '../../info/info-data.service'
|
import { InfoDataService, TaggedLayer } from '../../info/info-data.service'
|
||||||
|
@ -30,11 +30,11 @@ export class MapControlsComponent implements OnInit {
|
||||||
|
|
||||||
baseStyles: BaseStyle[]
|
baseStyles: BaseStyle[]
|
||||||
|
|
||||||
baseStyleOpacity: number = this.configService.conf.value.map['opacity']
|
baseStyleOpacity: number = this.configService.conf.value.bsData?.map.opacity
|
||||||
|
|
||||||
status = new FormControl([])
|
status = new FormControl([])
|
||||||
|
|
||||||
canCreateBaseMap: boolean = false
|
// canCreateBaseMap: boolean = false
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public snackBar: MatSnackBar,
|
public snackBar: MatSnackBar,
|
||||||
|
@ -42,7 +42,7 @@ export class MapControlsComponent implements OnInit {
|
||||||
public mapControlService: MapControlService,
|
public mapControlService: MapControlService,
|
||||||
protected infoDataService: InfoDataService,
|
protected infoDataService: InfoDataService,
|
||||||
public mapDataService: MapDataService,
|
public mapDataService: MapDataService,
|
||||||
private authenticationService: AuthenticationService,
|
public authenticationService: AuthenticationService,
|
||||||
public dialog: MatDialog,
|
public dialog: MatDialog,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
@ -102,11 +102,11 @@ export class MapControlsComponent implements OnInit {
|
||||||
this.mapControlService.status.next(value)
|
this.mapControlService.status.next(value)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
this.status.setValue(this.configService.conf.value.map['defaultStatus'])
|
this.status.setValue(this.configService.conf.value.bsData?.map['defaultStatus'])
|
||||||
|
|
||||||
this.mapControlService.baseStyleOpacity.next(this.baseStyleOpacity)
|
this.mapControlService.baseStyleOpacity.next(this.baseStyleOpacity)
|
||||||
|
|
||||||
this.canCreateBaseMap = this.authenticationService.isAuthorized(['base_map_creator'])
|
// this.canCreateBaseMap = this.authenticationService.isAuthorized(['base_map_creator'])
|
||||||
}
|
}
|
||||||
|
|
||||||
openSnackBar(msg: string):void {
|
openSnackBar(msg: string):void {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import Point from '@mapbox/point-geometry'
|
||||||
import * as bbox from '@turf/bbox'
|
import * as bbox from '@turf/bbox'
|
||||||
|
|
||||||
import { GeoJsonService, LiveGeoJsonService, MapboxDataAndStyle } from '../../_services/geojson.service'
|
import { GeoJsonService, LiveGeoJsonService, MapboxDataAndStyle } from '../../_services/geojson.service'
|
||||||
import { ConfigService } from '../../config.service'
|
import { ConfigService } from '../../_services/config.service'
|
||||||
import { MapControlService } from '../map-control.service'
|
import { MapControlService } from '../map-control.service'
|
||||||
import { LayerNode } from '../models'
|
import { LayerNode } from '../models'
|
||||||
import { InfoDataService, Feature, TaggedLayer, FeatureWithField, TaggedFeature } from '../../info/info-data.service'
|
import { InfoDataService, Feature, TaggedLayer, FeatureWithField, TaggedFeature } from '../../info/info-data.service'
|
||||||
|
@ -52,15 +52,15 @@ export class GisafMapboxComponent implements OnInit, OnDestroy {
|
||||||
// XXX: temporary, for keeping map-controls.component.ts happy
|
// XXX: temporary, for keeping map-controls.component.ts happy
|
||||||
map: Map
|
map: Map
|
||||||
|
|
||||||
zoom: number = this.configService.conf.value.map['zoom']
|
zoom: number = this.configService.conf.value.bsData?.map['zoom']
|
||||||
pitch: number = this.configService.conf.value.map['pitch']
|
pitch: number = this.configService.conf.value.bsData?.map['pitch']
|
||||||
lat: number = this.configService.conf.value.map['lat']
|
lat: number = this.configService.conf.value.bsData?.map['lat']
|
||||||
lng: number = this.configService.conf.value.map['lng']
|
lng: number = this.configService.conf.value.bsData?.map['lng']
|
||||||
bearing: number = this.configService.conf.value.map['bearing']
|
bearing: number = this.configService.conf.value.bsData?.map['bearing']
|
||||||
globalAttribution: string = this.configService.conf.value.map['attribution']
|
globalAttribution: string = this.configService.conf.value.bsData?.map['attribution']
|
||||||
|
|
||||||
baseStyle: BaseStyle = new BaseStyle('None')
|
baseStyle: BaseStyle = new BaseStyle('None')
|
||||||
protected _baseStyleName: string = this.configService.conf.value.map['style']
|
protected _baseStyleName: string = this.configService.conf.value.bsData?.map['style']
|
||||||
protected _bottom: number = 0
|
protected _bottom: number = 0
|
||||||
|
|
||||||
protected canvas: HTMLElement
|
protected canvas: HTMLElement
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { Subject, BehaviorSubject, forkJoin } from 'rxjs'
|
import { Subject, BehaviorSubject, forkJoin } from 'rxjs'
|
||||||
|
|
||||||
import { ConfigService } from '../config.service'
|
import { ConfigService } from '../_services/config.service'
|
||||||
import { LayerNode } from './models'
|
import { LayerNode } from './models'
|
||||||
import { TaggedLayer, Feature, FeatureWithField } from '../info/info-data.service'
|
import { TaggedLayer, Feature, FeatureWithField } from '../info/info-data.service'
|
||||||
import { BaseMapWithStores } from '../openapi'
|
import { BaseMapWithStores } from '../openapi'
|
||||||
|
@ -35,11 +35,11 @@ export class MapControlService {
|
||||||
public tempSelection = new BehaviorSubject<Object>({})
|
public tempSelection = new BehaviorSubject<Object>({})
|
||||||
public search = new Subject<boolean>()
|
public search = new Subject<boolean>()
|
||||||
public baseMapLayers: BehaviorSubject<Set<string>> = new BehaviorSubject(new Set())
|
public baseMapLayers: BehaviorSubject<Set<string>> = new BehaviorSubject(new Set())
|
||||||
public status = new BehaviorSubject<string[]>(this.configService.conf.value.map['defaultStatus'])
|
public status = new BehaviorSubject<string[]>(this.configService.conf.value.bsData?.map['defaultStatus'])
|
||||||
public hasLabels = new BehaviorSubject<boolean>(false)
|
public hasLabels = new BehaviorSubject<boolean>(false)
|
||||||
public hasTags = new BehaviorSubject<boolean>(false)
|
public hasTags = new BehaviorSubject<boolean>(false)
|
||||||
public layerLoaded = new Subject<LayerNode>()
|
public layerLoaded = new Subject<LayerNode>()
|
||||||
public baseStyleName = new BehaviorSubject<string>(this.configService.conf.value.map['style'])
|
public baseStyleName = new BehaviorSubject<string>(this.configService.conf.value.bsData?.map['style'])
|
||||||
public addBaseMap = new Subject<BaseMapWithStores>()
|
public addBaseMap = new Subject<BaseMapWithStores>()
|
||||||
|
|
||||||
public mapLoaded = new BehaviorSubject<boolean>(false)
|
public mapLoaded = new BehaviorSubject<boolean>(false)
|
||||||
|
|
|
@ -89,7 +89,7 @@ export class MapDataService {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
getBaseStyle(styleName: string): Observable<BaseStyle> {
|
getBaseStyle(styleName: string): Observable<BaseStyle> {
|
||||||
return this.mapService.getBaseStyleApiMapBaseStyleNameGet({name: styleName}).pipe(map(
|
return this.mapService.getBaseStyleApiMapBaseStyleNameGet(styleName).pipe(map(
|
||||||
data => new BaseStyle(data.name, <any>data.style)
|
data => new BaseStyle(data.name, <any>data.style)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
<ng-template matMenuContent let-node="node">
|
<ng-template matMenuContent let-node="node">
|
||||||
<button mat-menu-item (click)="downloadGpkg(node)">
|
<button mat-menu-item (click)="downloadGpkg(node)">
|
||||||
<mat-icon>file_download</mat-icon>
|
<mat-icon>file_download</mat-icon>
|
||||||
<span>Download Geopackage (EPSG {{ (configService.conf | async).geo['srid'] }})</span>
|
<span>Download Geopackage (EPSG {{ (configService.conf | async).bsData?.geo.srid_for_proj }})</span>
|
||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
@ -55,19 +55,19 @@
|
||||||
<ng-template matMenuContent let-node="node">
|
<ng-template matMenuContent let-node="node">
|
||||||
<button mat-menu-item (click)="downloadGpkg(node)">
|
<button mat-menu-item (click)="downloadGpkg(node)">
|
||||||
<mat-icon>file_download</mat-icon>
|
<mat-icon>file_download</mat-icon>
|
||||||
<span>Download Geopackage (EPSG {{ (configService.conf | async).proj['srid'] }})</span>
|
<span>Download Geopackage (EPSG {{ (configService.conf | async).bsData?.geo.srid_for_proj }})</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item (click)="downloadDXF(node)">
|
<button mat-menu-item (click)="downloadDXF(node)">
|
||||||
<mat-icon>file_download</mat-icon>
|
<mat-icon>file_download</mat-icon>
|
||||||
<span>Download DXF (EPSG {{ (configService.conf | async).proj['srid'] }})</span>
|
<span>Download DXF (EPSG {{ (configService.conf | async).bsData?.geo.proj })</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item (click)="downloadDXF(node, true)">
|
<button mat-menu-item (click)="downloadDXF(node, true)">
|
||||||
<mat-icon>file_download</mat-icon>
|
<mat-icon>file_download</mat-icon>
|
||||||
<span>Download DXF (reprojected to EPSG {{ (configService.conf | async).proj['srid_for_proj'] }})</span>
|
<span>Download DXF (reprojected to EPSG {{ (configService.conf | async).bsData?.geo.srid_for_proj }})</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item (click)="downloadLayer(node)">
|
<button mat-menu-item (click)="downloadLayer(node)">
|
||||||
<mat-icon>file_download</mat-icon>
|
<mat-icon>file_download</mat-icon>
|
||||||
<span>Download Shapefile (EPSG {{ (configService.conf | async).proj['srid'] }}) [<i><b>Deprecated</b>: use Geopackage</i>]</span>
|
<span>Download Shapefile (EPSG {{ (configService.conf | async).bsData?.geo.srid }}) [<i><b>Deprecated</b>: use Geopackage</i>]</span>
|
||||||
</button>
|
</button>
|
||||||
<button mat-menu-item (click)="downloadRawData(node)" *ngIf="node.rawSurveyStore">
|
<button mat-menu-item (click)="downloadRawData(node)" *ngIf="node.rawSurveyStore">
|
||||||
<mat-icon>file_download</mat-icon>
|
<mat-icon>file_download</mat-icon>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { MatSnackBar } from '@angular/material/snack-bar'
|
||||||
|
|
||||||
import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'
|
import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'
|
||||||
|
|
||||||
import { ConfigService } from '../../config.service'
|
import { ConfigService } from '../../_services/config.service'
|
||||||
import { Node, PrimaryGroupNode, LayerNode, TreeData } from '../models'
|
import { Node, PrimaryGroupNode, LayerNode, TreeData } from '../models'
|
||||||
import { MapControlService } from '../map-control.service'
|
import { MapControlService } from '../map-control.service'
|
||||||
import { MapDataService } from '../map-data.service'
|
import { MapDataService } from '../map-data.service'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'
|
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'
|
||||||
import { ActivatedRoute, Router, ParamMap } from '@angular/router'
|
import { ActivatedRoute, Router, ParamMap } from '@angular/router'
|
||||||
import { ConfigService } from '../../config.service'
|
import { ConfigService } from '../../_services/config.service'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'gisaf-measures-home',
|
selector: 'gisaf-measures-home',
|
||||||
|
@ -14,8 +14,8 @@ export class MeasuresHomeComponent implements OnInit {
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.configService.conf.subscribe(
|
this.configService.conf.subscribe(
|
||||||
conf => {
|
conf => {
|
||||||
if (conf.measures) {
|
if (conf.bsData?.measures) {
|
||||||
this.router.navigate(['/measures', conf.measures['defaultStore']])
|
this.router.navigate(['/measures', conf.bsData.measures['defaultStore']])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { Observable, of } from 'rxjs'
|
||||||
import { map, startWith, switchMap } from 'rxjs/operators'
|
import { map, startWith, switchMap } from 'rxjs/operators'
|
||||||
|
|
||||||
import { DataService } from '../../_services/data.service'
|
import { DataService } from '../../_services/data.service'
|
||||||
import { ConfigService } from '../../config.service'
|
import { ConfigService } from '../../_services/config.service'
|
||||||
import { MeasuresItem, DataProvider } from '../../openapi'
|
import { MeasuresItem, DataProvider } from '../../openapi'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { map, startWith, switchMap } from 'rxjs/operators'
|
||||||
import { Observable, of } from 'rxjs'
|
import { Observable, of } from 'rxjs'
|
||||||
|
|
||||||
import { DataService } from '../_services/data.service'
|
import { DataService } from '../_services/data.service'
|
||||||
import { ConfigService } from '../config.service'
|
import { ConfigService } from '../_services/config.service'
|
||||||
import { DataProvider } from '../openapi'
|
import { DataProvider } from '../openapi'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|
|
@ -21,7 +21,7 @@ export type OpenAPIConfig = {
|
||||||
|
|
||||||
export const OpenAPI: OpenAPIConfig = {
|
export const OpenAPI: OpenAPIConfig = {
|
||||||
BASE: '',
|
BASE: '',
|
||||||
VERSION: '2023.4.dev37+gb00bf1f.d20240226',
|
VERSION: '2023.4.dev51+g15fe7fa.d20240318',
|
||||||
WITH_CREDENTIALS: false,
|
WITH_CREDENTIALS: false,
|
||||||
CREDENTIALS: 'include',
|
CREDENTIALS: 'include',
|
||||||
TOKEN: undefined,
|
TOKEN: undefined,
|
||||||
|
|
|
@ -29,14 +29,13 @@ export class AdminService {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get Basket
|
* Get Basket
|
||||||
|
* @param name
|
||||||
* @returns AdminBasket Successful Response
|
* @returns AdminBasket Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getBasketApiAdminBasketNameGet({
|
public getBasketApiAdminBasketNameGet(
|
||||||
name,
|
|
||||||
}: {
|
|
||||||
name: string,
|
name: string,
|
||||||
}): Observable<AdminBasket> {
|
): Observable<AdminBasket> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/admin/basket/{name}',
|
url: '/api/admin/basket/{name}',
|
||||||
|
|
|
@ -43,14 +43,13 @@ export class ApiService {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Login For Access Token
|
* Login For Access Token
|
||||||
|
* @param formData
|
||||||
* @returns Token Successful Response
|
* @returns Token Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public loginForAccessTokenApiTokenPost({
|
public loginForAccessTokenApiTokenPost(
|
||||||
formData,
|
|
||||||
}: {
|
|
||||||
formData: Body_login_for_access_token_api_token_post,
|
formData: Body_login_for_access_token_api_token_post,
|
||||||
}): Observable<Token> {
|
): Observable<Token> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: '/api/token',
|
url: '/api/token',
|
||||||
|
@ -62,6 +61,20 @@ export class ApiService {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Logout
|
||||||
|
* @returns any Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public logoutApiLogoutGet(): Observable<any> {
|
||||||
|
return __request(OpenAPI, this.http, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/api/logout',
|
||||||
|
errors: {
|
||||||
|
404: `Not found`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Get Users
|
* Get Users
|
||||||
* @returns UserRead Successful Response
|
* @returns UserRead Successful Response
|
||||||
|
@ -154,14 +167,13 @@ export class ApiService {
|
||||||
* Json REST store API compatible with Flask Potion and Angular
|
* Json REST store API compatible with Flask Potion and Angular
|
||||||
* Get the list of items (used for making the list of items in measures)
|
* Get the list of items (used for making the list of items in measures)
|
||||||
* Filter only items with at least one measure
|
* Filter only items with at least one measure
|
||||||
|
* @param store
|
||||||
* @returns MeasuresItem Successful Response
|
* @returns MeasuresItem Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getModelListApiDataProviderStoreGet({
|
public getModelListApiDataProviderStoreGet(
|
||||||
store,
|
|
||||||
}: {
|
|
||||||
store: string,
|
store: string,
|
||||||
}): Observable<Array<MeasuresItem>> {
|
): Observable<Array<MeasuresItem>> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/data-provider/{store}',
|
url: '/api/data-provider/{store}',
|
||||||
|
@ -177,20 +189,19 @@ export class ApiService {
|
||||||
/**
|
/**
|
||||||
* Get Model Values
|
* Get Model Values
|
||||||
* Get values
|
* Get values
|
||||||
|
* @param storeName
|
||||||
|
* @param value
|
||||||
|
* @param where
|
||||||
|
* @param resample
|
||||||
* @returns any Successful Response
|
* @returns any Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getModelValuesApiStoreNameValuesValueGet({
|
public getModelValuesApiStoreNameValuesValueGet(
|
||||||
storeName,
|
|
||||||
value,
|
|
||||||
where,
|
|
||||||
resample,
|
|
||||||
}: {
|
|
||||||
storeName: string,
|
storeName: string,
|
||||||
value: string,
|
value: string,
|
||||||
where: string,
|
where: string,
|
||||||
resample?: (string | null),
|
resample?: (string | null),
|
||||||
}): Observable<any> {
|
): Observable<any> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/{store_name}/values/{value}',
|
url: '/api/{store_name}/values/{value}',
|
||||||
|
@ -252,16 +263,15 @@ export class ApiService {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get Feature Info
|
* Get Feature Info
|
||||||
|
* @param store
|
||||||
|
* @param id
|
||||||
* @returns any Successful Response
|
* @returns any Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getFeatureInfoApiFeatureInfoStoreIdGet({
|
public getFeatureInfoApiFeatureInfoStoreIdGet(
|
||||||
store,
|
|
||||||
id,
|
|
||||||
}: {
|
|
||||||
store: string,
|
store: string,
|
||||||
id: string,
|
id: string,
|
||||||
}): Observable<(FeatureInfo | null)> {
|
): Observable<(FeatureInfo | null)> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/feature-info/{store}/{id}',
|
url: '/api/feature-info/{store}/{id}',
|
||||||
|
@ -277,14 +287,13 @@ export class ApiService {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get Model Info
|
* Get Model Info
|
||||||
|
* @param store
|
||||||
* @returns ModelInfo Successful Response
|
* @returns ModelInfo Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getModelInfoApiModelInfoStoreGet({
|
public getModelInfoApiModelInfoStoreGet(
|
||||||
store,
|
|
||||||
}: {
|
|
||||||
store: string,
|
store: string,
|
||||||
}): Observable<ModelInfo> {
|
): Observable<ModelInfo> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/model-info/{store}',
|
url: '/api/model-info/{store}',
|
||||||
|
@ -299,18 +308,17 @@ export class ApiService {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get Plot Params
|
* Get Plot Params
|
||||||
|
* @param store
|
||||||
|
* @param id
|
||||||
|
* @param value
|
||||||
* @returns PlotParams Successful Response
|
* @returns PlotParams Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getPlotParamsApiPlotParamsStoreGet({
|
public getPlotParamsApiPlotParamsStoreGet(
|
||||||
store,
|
|
||||||
id,
|
|
||||||
value,
|
|
||||||
}: {
|
|
||||||
store: string,
|
store: string,
|
||||||
id: string,
|
id: string,
|
||||||
value: string,
|
value: string,
|
||||||
}): Observable<PlotParams> {
|
): Observable<PlotParams> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/plot-params/{store}',
|
url: '/api/plot-params/{store}',
|
||||||
|
|
|
@ -45,16 +45,15 @@ export class DashboardService {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get Dashboard Page
|
* Get Dashboard Page
|
||||||
|
* @param group
|
||||||
|
* @param name
|
||||||
* @returns DashboardPage_ Successful Response
|
* @returns DashboardPage_ Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getDashboardPageApiDashboardPageGroupNameGet({
|
public getDashboardPageApiDashboardPageGroupNameGet(
|
||||||
group,
|
|
||||||
name,
|
|
||||||
}: {
|
|
||||||
group: string,
|
group: string,
|
||||||
name: string,
|
name: string,
|
||||||
}): Observable<DashboardPage_> {
|
): Observable<DashboardPage_> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/dashboard/page/{group}/{name}',
|
url: '/api/dashboard/page/{group}/{name}',
|
||||||
|
|
|
@ -17,20 +17,19 @@ export class GeoapiService {
|
||||||
* Some REST stores coded manually (route prefixed with "gj": geojson).
|
* Some REST stores coded manually (route prefixed with "gj": geojson).
|
||||||
* :param store_name: name of the model
|
* :param store_name: name of the model
|
||||||
* :return: json
|
* :return: json
|
||||||
|
* @param storeName
|
||||||
|
* @param ifNoneMatch
|
||||||
|
* @param simplify
|
||||||
|
* @param preserveTopology
|
||||||
* @returns any Successful Response
|
* @returns any Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getGeojsonApiGjStoreNameGet({
|
public getGeojsonApiGjStoreNameGet(
|
||||||
storeName,
|
|
||||||
ifNoneMatch,
|
|
||||||
simplify,
|
|
||||||
preserveTopology,
|
|
||||||
}: {
|
|
||||||
storeName: any,
|
storeName: any,
|
||||||
ifNoneMatch?: (string | null),
|
ifNoneMatch?: (string | null),
|
||||||
simplify?: (number | null),
|
simplify?: (number | null),
|
||||||
preserveTopology?: (boolean | null),
|
preserveTopology?: (boolean | null),
|
||||||
}): Observable<any> {
|
): Observable<any> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/gj/{store_name}',
|
url: '/api/gj/{store_name}',
|
||||||
|
|
|
@ -28,14 +28,13 @@ export class MapService {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get Base Style
|
* Get Base Style
|
||||||
|
* @param name
|
||||||
* @returns BaseStyle Successful Response
|
* @returns BaseStyle Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getBaseStyleApiMapBaseStyleNameGet({
|
public getBaseStyleApiMapBaseStyleNameGet(
|
||||||
name,
|
|
||||||
}: {
|
|
||||||
name: string,
|
name: string,
|
||||||
}): Observable<BaseStyle> {
|
): Observable<BaseStyle> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/map/base_style/{name}',
|
url: '/api/map/base_style/{name}',
|
||||||
|
@ -49,14 +48,13 @@ export class MapService {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get Layer Style
|
* Get Layer Style
|
||||||
|
* @param store
|
||||||
* @returns any Successful Response
|
* @returns any Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public getLayerStyleApiMapLayerStyleStoreGet({
|
public getLayerStyleApiMapLayerStyleStoreGet(
|
||||||
store,
|
|
||||||
}: {
|
|
||||||
store: string,
|
store: string,
|
||||||
}): Observable<(MaplibreStyle | null)> {
|
): Observable<(MaplibreStyle | null)> {
|
||||||
return __request(OpenAPI, this.http, {
|
return __request(OpenAPI, this.http, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/api/map/layer_style/{store}',
|
url: '/api/map/layer_style/{store}',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue