Commit 15ebd1a2 authored by Vitali Stupin's avatar Vitali Stupin
Browse files

compact searchbox, restore scroll position on going back

parent 439a6fcf
......@@ -5,8 +5,11 @@ import { SubsystemComponent } from './subsystem/subsystem.component';
const routes: Routes = [
{ path: '', component: SubsystemListComponent },
// Redirecting old catalogue app links
{ path: ':instance/wsdls', redirectTo: '/:instance', pathMatch: 'full' },
{ path: ':instance', component: SubsystemListComponent },
{ path: ':instance/:class/:member/:subsystem', component: SubsystemComponent },
{ path: '**', redirectTo: '/' }
];
@NgModule({
......
......@@ -5,7 +5,7 @@ import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { SubsystemListComponent } from './subsystem-list/subsystem-list.component';
import { SearchComponent } from './search/search.component';
import { SearchComponent } from './subsystem-list/search/search.component';
import { SubsystemItemComponent } from './subsystem-list/subsystem-item/subsystem-item.component';
import { AppRoutingModule } from './app-routing.module';
import { SubsystemComponent } from './subsystem/subsystem.component';
......
......@@ -17,7 +17,6 @@ const API_SERVICE = 'index.json';
providedIn: 'root'
})
export class MethodsService {
private apiUrlBase = '';
private limit: number = 10;
private offset: number = 0;
......@@ -102,10 +101,9 @@ export class MethodsService {
/**
* Handle Http operation that failed.
* Let the app continue.
* @param operation - name of the operation that failed
* @param result - optional value to return as the observable result
*/
private handleError<T> (operation = 'operation', result?: T) {
private handleError<T> (result?: T) {
return (error: any): Observable<T> => {
this.loadingError = true
this.emitWarning('Error while loading data from server!')
......@@ -136,7 +134,7 @@ export class MethodsService {
this.apiUrlBase = CONFIG[instance]
// Data of this instance already loaded
if (this.instanceData[instance]) {
if (this.instanceData[instance] && this.instanceData[instance].length) {
this.subsystems = this.instanceData[instance]
this.signalRefresh();
} else {
......@@ -144,7 +142,7 @@ export class MethodsService {
this.loadingError = false;
this.http.get<Subsystem[]>(this.apiUrlBase + API_SERVICE)
.pipe(
catchError(this.handleError('getMethods', []))
catchError(this.handleError([]))
).subscribe(subsystems => {
this.instanceData[instance] = subsystems
this.subsystems = this.instanceData[instance]
......
<div class="card">
<div class="card-header">
Search filters
</div>
<div class="card-body">
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="nonEmptyCheck"
[(ngModel)]="nonEmpty" (change)="setNonEmpty(nonEmpty)">
<label class="form-check-label" for="nonEmptyCheck">Show only producer subsystems</label>
</div>
<div class="form-group">
<label for="limitSelect">Amount of subsystems to display</label>
<select class="form-control" id="limitSelect"
[(ngModel)]="limit" (change)="setLimit(limit)">
<option>10</option>
<option>20</option>
<option>50</option>
<option>All</option>
</select>
</div>
<div class="form-group">
<label for="filterInput">Filter by method name</label>
<input type="text" class="form-control" id="filterInput"
[(ngModel)]="filter" (ngModelChange)="setFilter(filter)">
</div>
</div>
</div>
<br>
\ No newline at end of file
<div class="card">
<div class="card-header">
Search filters
</div>
<div class="card-body">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="filterInput">Filter by method name</label>
<input type="text" class="form-control" id="filterInput"
[(ngModel)]="filter" (ngModelChange)="setFilter(filter)">
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<label for="limitSelect">Amount of subsystems to display</label>
<select class="form-control" id="limitSelect"
[(ngModel)]="limit" (change)="setLimit(limit)">
<option>10</option>
<option>20</option>
<option>50</option>
<option>All</option>
</select>
</div>
</div>
<div class="col-sm-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="nonEmptyCheck"
[(ngModel)]="nonEmpty" (change)="setNonEmpty(nonEmpty)">
<label class="form-check-label" for="nonEmptyCheck">Show only producer subsystems</label>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { MethodsService } from '../methods.service';
import { MethodsService } from '../../methods.service';
@Component({
selector: 'app-search',
......
......@@ -18,6 +18,7 @@
</div>
<app-search></app-search>
<br>
<div *ngFor="let subsystem of subsystems">
<app-subsystem-item [subsystem]="subsystem"></app-subsystem-item>
......
import { Component, OnInit } from '@angular/core';
import { Subsystem } from '../subsystem';
import { MethodsService } from '../methods.service';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute, Router, Scroll } from '@angular/router';
import { Subscription } from 'rxjs';
import { ViewportScroller } from '@angular/common';
import { filter } from 'rxjs/operators';
@Component({
selector: 'app-subsystem-list',
......@@ -11,23 +14,43 @@ import { ActivatedRoute, Router } from '@angular/router';
export class SubsystemListComponent implements OnInit {
subsystems: Subsystem[]
message: string = ''
scrollPosition: [number, number]
routerScrollSubscription: Subscription
routeSubscription: Subscription
updatedSubscription: Subscription
warningsSubscription: Subscription
constructor(
private methodsService: MethodsService,
private route: ActivatedRoute,
private router: Router
) {}
private router: Router,
private viewportScroller: ViewportScroller
) {
// Geting previous scroll position
this.routerScrollSubscription = this.router.events.pipe(
filter(e => e instanceof Scroll)
).subscribe(e => {
if ((e as Scroll).position) {
this.scrollPosition = (e as Scroll).position;
} else {
this.scrollPosition = [0, 0];
}
});
}
ngOnInit() {
// Reset message on page load
this.message = ''
// Service will tell when data loading failed!
this.methodsService.warnings.subscribe(signal => {
this.warningsSubscription = this.methodsService.warnings.subscribe(signal => {
this.message = signal
});
this.route.params.subscribe( params => {
this.routeSubscription = this.route.params.subscribe( params => {
// Reset message on navigation
this.message = ''
// Redirect to default instance if instance is empty or invalid
if (!this.methodsService.getInstances().includes(params['instance'])) {
this.router.navigateByUrl('/' + this.methodsService.getDefaultInstance())
......@@ -40,7 +63,7 @@ export class SubsystemListComponent implements OnInit {
});
// Service will tell when updated data is available!
this.methodsService.subsystemsUpdated.subscribe(signal => {
this.updatedSubscription = this.methodsService.subsystemsUpdated.subscribe(signal => {
this.getMethods();
});
// If json data is loaded update event will not be emited.
......@@ -48,6 +71,18 @@ export class SubsystemListComponent implements OnInit {
this.getMethods();
}
ngAfterViewInit() {
// Restoring scroll position
this.viewportScroller.scrollToPosition(this.scrollPosition);
}
ngOnDestroy() {
this.routerScrollSubscription.unsubscribe()
this.routeSubscription.unsubscribe()
this.updatedSubscription.unsubscribe()
this.warningsSubscription.unsubscribe()
}
getInstance(): string {
return this.methodsService.getInstance()
}
......
import { Method } from './method';
// TODO: use two classes for parsing of json and for use by application
export class Subsystem {
memberClass: string;
subsystemCode: string;
......
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { MethodsService } from '../methods.service';
import { Subsystem } from '../subsystem';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-subsystem',
templateUrl: './subsystem.component.html',
styleUrls: ['./subsystem.component.css']
})
export class SubsystemComponent implements OnInit {
export class SubsystemComponent implements OnInit, OnDestroy {
subsystem: Subsystem
subsystemId: string
message: string = ''
routeSubscription: Subscription
updatedSubscription: Subscription
warningsSubscription: Subscription
constructor(
private methodsService: MethodsService,
......@@ -31,11 +35,11 @@ export class SubsystemComponent implements OnInit {
this.message = ''
// Service will tell when data loading failed!
this.methodsService.warnings.subscribe(signal => {
this.warningsSubscription = this.methodsService.warnings.subscribe(signal => {
this.message = signal
});
this.route.params.subscribe( params => {
this.routeSubscription = this.route.params.subscribe( params => {
// Checking if instance is correct
if (!this.methodsService.getInstances().includes(params['instance'])) {
this.message = 'Incorrect instance!'
......@@ -49,12 +53,11 @@ export class SubsystemComponent implements OnInit {
});
// Service will tell when data has finished loading
this.methodsService.subsystemsUpdated.subscribe(signal => {
this.updatedSubscription = this.methodsService.subsystemsUpdated.subscribe(signal => {
this.subsystem = this.methodsService.getSubsystem(this.subsystemId)
if (this.methodsService.isLoadingDone() && !this.methodsService.isLoadingError()) {
this.checkSubsystem()
}
// TODO: No need to recheck after loading is done
});
// If json data is loaded update event will not be emited.
// This line must be after subscription (data may be changed while we start subscription)
......@@ -64,6 +67,12 @@ export class SubsystemComponent implements OnInit {
}
}
ngOnDestroy() {
this.routeSubscription.unsubscribe()
this.updatedSubscription.unsubscribe()
this.warningsSubscription.unsubscribe()
}
getInstance(): string {
return this.methodsService.getInstance()
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment