Commit 753f9357 authored by Vitali Stupin's avatar Vitali Stupin
Browse files

Refactoring

parent 03b9b2d4
......@@ -3,26 +3,25 @@
## Building
```
sudo apt install nodejs
sudo apt install npm
sudo npm install -g npm@latest
sudo npm install -g @angular/cli
sudo apt install nodejs npm
sudo -H npm install -g npm@latest
sudo -H npm install -g @angular/cli
git clone <this_repository>
npm install
cd <this_repository_name>
npm ci
```
## Testing locally
## Updating angular version
```
ng serve --host 0.0.0.0
ng update @angular/cli @angular/core
```
## Update angular
## Deploy for local manual testing
```
ng update @angular/cli @angular/core
ng serve --host 0.0.0.0
```
## Build for production
```
ng build --prod --base-href /methods/
ng build --prod --base-href /catalogue/
```
# Methods
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.3.2.
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
## Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
export const MAX_LIMIT: number = 1000000;
export const DEFAULT_LIMIT: number = 10;
export const INSTANCES = {
'EE': 'https://www.x-tee.ee/catalogue/EE/wsdls/',
'ee-test': 'https://www.x-tee.ee/catalogue/ee-test/wsdls/',
'ee-dev': 'https://www.x-tee.ee/catalogue/ee-dev/wsdls/'
}
export const API_SERVICE = 'index.json';
export const LANGUAGES = {
'EST': 'est',
'ENG': 'eng'
}
export const PREVIEW_SIZE: number = 5
......@@ -10,9 +10,6 @@ export class HeaderComponent implements OnInit {
constructor(private languagesService: LanguagesService) { }
ngOnInit() {
}
getLangs():string[] {
return this.languagesService.getLangs()
}
......@@ -24,4 +21,6 @@ export class HeaderComponent implements OnInit {
setLang(lang: string) {
return this.languagesService.setLang(lang)
}
ngOnInit() {}
}
......@@ -3,11 +3,7 @@ import {TranslateService} from "@ngx-translate/core";
import { Title } from '@angular/platform-browser';
import { Subscription } from 'rxjs';
import { take } from 'rxjs/operators';
const LANGUAGES = {
'EST': 'est',
'ENG': 'eng'
}
import { LANGUAGES } from './config'
@Injectable({
providedIn: 'root'
......@@ -41,14 +37,14 @@ export class LanguagesService {
return Object.keys(LANGUAGES)[0]
}
getLang(): string {
return this.selectedLang
}
getLangs(): string[] {
return Object.keys(LANGUAGES)
}
getLang(): string {
return this.selectedLang
}
setLang(lang: string): void {
this.selectedLang = lang
if(window && window.localStorage) {
......
import { Component, OnInit } from '@angular/core';
import { MethodsService } from '../../methods.service';
import { SubsystemsService } from '../../subsystems.service';
@Component({
selector: 'app-search',
......@@ -12,24 +12,23 @@ export class SearchComponent implements OnInit {
nonEmpty: boolean
filter: string
constructor(private methodsService: MethodsService) { }
ngOnInit() {
this.limit = this.methodsService.getLimit()
this.nonEmpty = this.methodsService.getNonEmpty()
this.filter = this.methodsService.getfilter()
}
constructor(private subsystemsService: SubsystemsService) { }
setNonEmpty(nonEmpty: boolean) {
this.methodsService.setNonEmpty(nonEmpty)
this.subsystemsService.setNonEmpty(nonEmpty)
}
setLimit(limit: string) {
this.methodsService.setLimit(limit)
this.subsystemsService.setLimit(limit)
}
setFilter(filter: string) {
this.methodsService.setFilter(filter)
this.subsystemsService.setFilter(filter)
}
ngOnInit() {
this.limit = this.subsystemsService.getLimit()
this.nonEmpty = this.subsystemsService.getNonEmpty()
this.filter = this.subsystemsService.getfilter()
}
}
import { Component, OnInit, Input } from '@angular/core';
import { Subsystem } from '../../subsystem';
import { Method } from '../../method';
import { MethodsService } from '../../methods.service';
import { SubsystemsService } from '../../subsystems.service';
import { Router } from '@angular/router';
import { PREVIEW_SIZE } from '../../config'
@Component({
selector: 'app-subsystem-item',
......@@ -10,31 +11,26 @@ import { Router } from '@angular/router';
styleUrls: ['./subsystem-item.component.css']
})
export class SubsystemItemComponent implements OnInit {
@Input() subsystem: Subsystem
private previewSize: number = 5
constructor(
private methodsService: MethodsService,
private subsystemsService: SubsystemsService,
private router: Router
) { }
ngOnInit() {
}
getApiUrlBase(): string {
return this.methodsService.getApiUrlBase()
return this.subsystemsService.getApiUrlBase()
}
getMethodsPreview(): Method[] {
return this.subsystem.methods.length ? this.subsystem.methods.slice(0, this.previewSize) : []
return this.subsystem.methods.length ? this.subsystem.methods.slice(0, PREVIEW_SIZE) : []
}
getNotInPreview(): number {
if (this.subsystem.methods.length - this.previewSize < 0) {
if (this.subsystem.methods.length - PREVIEW_SIZE < 0) {
return 0
}
return this.subsystem.methods.length - this.previewSize
return this.subsystem.methods.length - PREVIEW_SIZE
}
showDetail() {
......@@ -45,4 +41,6 @@ export class SubsystemItemComponent implements OnInit {
+ '/' + this.subsystem.subsystemCode
)
}
ngOnInit() {}
}
......@@ -20,6 +20,6 @@
<app-search></app-search>
<br>
<div *ngFor="let subsystem of subsystems">
<div *ngFor="let subsystem of filteredSubsystems | async">
<app-subsystem-item [subsystem]="subsystem"></app-subsystem-item>
</div>
......@@ -3,8 +3,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { HttpClientModule } from '@angular/common/http';
import { RouterTestingModule } from '@angular/router/testing'
import { SubsystemListComponent } from './subsystem-list.component';
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { ViewportScroller } from '@angular/common';
import { Component, Input } from '@angular/core';
import { Subsystem } from '../subsystem';
import { ActivatedRoute } from '@angular/router';
import { of } from 'rxjs';
......
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subsystem } from '../subsystem';
import { MethodsService } from '../methods.service';
import { SubsystemsService } from '../subsystems.service';
import { ActivatedRoute, Router, Scroll } from '@angular/router';
import { Subscription, BehaviorSubject } from 'rxjs';
import { ViewportScroller } from '@angular/common';
......@@ -17,12 +17,12 @@ export class SubsystemListComponent implements OnInit, OnDestroy {
scrollSubject: BehaviorSubject<any> = new BehaviorSubject(null);
routerScrollSubscription: Subscription
routeSubscription: Subscription
updatedSubscription: Subscription
warningsSubscription: Subscription
scrollSubjectSubscription: Subscription
filteredSubsystems: BehaviorSubject<Subsystem[]>
constructor(
private methodsService: MethodsService,
private subsystemsService: SubsystemsService,
private route: ActivatedRoute,
private router: Router,
private viewportScroller: ViewportScroller
......@@ -37,12 +37,29 @@ export class SubsystemListComponent implements OnInit, OnDestroy {
});
}
getInstance(): string {
return this.subsystemsService.getInstance()
}
getInstances(): string[] {
return this.subsystemsService.getInstances()
}
switchInstance(instance: string): void {
this.router.navigateByUrl('/' + instance)
}
getApiUrl(): string {
return this.subsystemsService.getApiUrl()
}
ngOnInit() {
// Reset message on page load
this.message = ''
this.filteredSubsystems = this.subsystemsService.filteredSubsystemsSubject
// Service will tell when data loading failed!
this.warningsSubscription = this.methodsService.warnings.subscribe(signal => {
this.warningsSubscription = this.subsystemsService.warnings.subscribe(signal => {
this.message = signal
});
......@@ -51,23 +68,15 @@ export class SubsystemListComponent implements OnInit, OnDestroy {
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())
if (!this.subsystemsService.getInstances().includes(params['instance'])) {
this.router.navigateByUrl('/' + this.subsystemsService.getDefaultInstance())
return
}
// Only reload on switching of instance or when no instance is selected yet on service side
if (this.getInstance() == '' || this.getInstance() != params['instance']) {
this.methodsService.setInstance(params['instance'] ? params['instance'] : this.methodsService.getDefaultInstance())
this.subsystemsService.setInstance(params['instance'] ? params['instance'] : this.subsystemsService.getDefaultInstance())
}
});
// Service will tell when updated data is available!
this.updatedSubscription = this.methodsService.subsystemsUpdated.subscribe(signal => {
this.getMethods();
});
// 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)
this.getMethods();
}
ngAfterViewInit() {
......@@ -82,28 +91,7 @@ export class SubsystemListComponent implements OnInit, OnDestroy {
ngOnDestroy() {
this.routerScrollSubscription.unsubscribe()
this.routeSubscription.unsubscribe()
this.updatedSubscription.unsubscribe()
this.warningsSubscription.unsubscribe()
this.scrollSubjectSubscription.unsubscribe()
}
getInstance(): string {
return this.methodsService.getInstance()
}
getInstances(): string[] {
return this.methodsService.getInstances()
}
getMethods(): void {
this.subsystems = this.methodsService.getMethods()
}
switchInstance(instance: string): void {
this.router.navigateByUrl('/' + instance)
}
getApiUrl(): string {
return this.methodsService.getApiUrl()
}
}
......@@ -9,7 +9,7 @@
<button type="button" class="btn btn-secondary" (click)="goToList()">{{'subsystem.allSystemsBtn' | translate}}</button>
<div *ngIf="subsystem">
<div *ngIf="(subsystemSubject | async) as subsystem">
<div class="card">
<div class="card-header">
{{subsystem.fullSubsystemName}}
......
......@@ -5,7 +5,7 @@ import { SubsystemComponent } from './subsystem.component';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientModule } from '@angular/common/http';
//import { ViewportScroller } from '@angular/common';
//import { MethodsService } from '../methods.service';
//import { SubsystemsService } from '../methods.service';
import { ActivatedRoute } from '@angular/router';
import { of } from 'rxjs';
......@@ -28,7 +28,7 @@ describe('SubsystemComponent', () => {
RouterTestingModule
]/*,
providers: [
MethodsService
SubsystemsService
]*/
})
.compileComponents();
......
import { Component, OnInit, OnDestroy } from '@angular/core';
import { MethodsService } from '../methods.service';
import { SubsystemsService } from '../subsystems.service';
import { Subsystem } from '../subsystem';
import { ActivatedRoute, Router, Scroll } from '@angular/router';
import { Subscription, BehaviorSubject } from 'rxjs';
......@@ -12,18 +12,18 @@ import { filter } from 'rxjs/operators';
styleUrls: ['./subsystem.component.css']
})
export class SubsystemComponent implements OnInit, OnDestroy {
subsystem: Subsystem
subsystemId: string
subsystemId: string = ''
message: string = ''
scrollSubject: BehaviorSubject<any> = new BehaviorSubject(null);
routerScrollSubscription: Subscription
routeSubscription: Subscription
updatedSubscription: Subscription
warningsSubscription: Subscription
scrollSubjectSubscription: Subscription
private scrollSubject: BehaviorSubject<any> = new BehaviorSubject(null)
private routerScrollSubscription: Subscription
private routeSubscription: Subscription
private warningsSubscription: Subscription
private scrollSubjectSubscription: Subscription
private subsystemsSubscription: Subscription
subsystemSubject: BehaviorSubject<Subsystem> = new BehaviorSubject(null)
constructor(
private methodsService: MethodsService,
private subsystemsService: SubsystemsService,
private route: ActivatedRoute,
private router: Router,
private viewportScroller: ViewportScroller
......@@ -38,48 +38,53 @@ export class SubsystemComponent implements OnInit, OnDestroy {
});
}
private checkSubsystem() {
// Do not overwrite previous warnings
if (!this.subsystem && !this.message) {
this.message = 'Subsystem "' + this.subsystemId + '" cannot be found!'
}
}
private getSubsystem(subsystems: Subsystem[], name: string): Subsystem {
return subsystems.find(function(element) {
return element.fullSubsystemName === name;
})
}
getInstance(): string {
return this.subsystemsService.getInstance()
}
getApiUrlBase(): string {
return this.subsystemsService.getApiUrlBase()
}
goToList(): void {
this.router.navigateByUrl('/' + this.subsystemsService.getInstance())
}
ngOnInit() {
// Reset message on page load
this.message = ''
// Service will tell when data loading failed!
this.warningsSubscription = this.methodsService.warnings.subscribe(signal => {
this.warningsSubscription = this.subsystemsService.warnings.subscribe(signal => {
this.message = signal
});
this.routeSubscription = this.route.params.subscribe( params => {
// Checking if instance is correct
if (!this.methodsService.getInstances().includes(params['instance'])) {
if (!this.subsystemsService.getInstances().includes(params['instance'])) {
this.message = 'Incorrect instance!'
return
}
this.subsystemId = params['instance'] + '/' + params['class'] + '/' + params['member'] + '/' + params['subsystem']
// Only reload on switching of instance or when no instance is selected yet on service side
if (this.getInstance() == '' || this.getInstance() != params['instance']) {
this.methodsService.setInstance(params['instance'] ? params['instance'] : this.methodsService.getDefaultInstance())
this.subsystemsService.setInstance(params['instance'] ? params['instance'] : this.subsystemsService.getDefaultInstance())
}
this.subsystemsSubscription = this.subsystemsService.subsystemsSubject.subscribe(subsystems => {
let subsystem = this.getSubsystem(subsystems, this.subsystemId)
if (!subsystem && !this.message) {
this.message = 'Subsystem "' + this.subsystemId + '" cannot be found!'
} else {
this.subsystemSubject.next(subsystem)
}
})
});
// Service will tell when data has finished loading
this.updatedSubscription = this.methodsService.subsystemsUpdated.subscribe(signal => {
this.subsystem = this.methodsService.getSubsystem(this.subsystemId)
if (this.methodsService.isLoadingDone() && !this.methodsService.isLoadingError()) {
this.checkSubsystem()
}
});
// 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)
if (this.subsystemId && this.methodsService.isLoadingDone() && !this.methodsService.isLoadingError()) {
this.subsystem = this.methodsService.getSubsystem(this.subsystemId)
this.checkSubsystem()
}
}
ngAfterViewInit() {
......@@ -94,20 +99,8 @@ export class SubsystemComponent implements OnInit, OnDestroy {
ngOnDestroy() {
this.routerScrollSubscription.unsubscribe()
this.routeSubscription.unsubscribe()
this.updatedSubscription.unsubscribe()
this.warningsSubscription.unsubscribe()
this.scrollSubjectSubscription.unsubscribe()
}
getInstance(): string {
return this.methodsService.getInstance()
}
getApiUrlBase(): string {
return this.methodsService.getApiUrlBase()
}
goToList(): void {
this.router.navigateByUrl('/' + this.methodsService.getInstance())
this.subsystemsSubscription.unsubscribe()
}
}
import { TestBed } from '@angular/core/testing';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { MethodsService } from './methods.service';
import { SubsystemsService } from './subsystems.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { HttpLoaderFactory } from './app.module';
describe('MethodsService', () => {
describe('SubsystemsService', () => {
beforeEach(() => TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot({
......@@ -19,7 +19,7 @@ describe('MethodsService', () => {
}));
it('should be created', () => {
const service: MethodsService = TestBed.get(MethodsService);
const service: SubsystemsService = TestBed.get(SubsystemsService);
expect(service).toBeTruthy();
});
});
\ No newline at end of file
import { Injectable, Output, EventEmitter } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { Observable, of, BehaviorSubject } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Subsystem } from './subsystem';
import { Method } from './method';
const MAX_LIMIT: number = 1000000;
const CONFIG = {
'EE': 'https://www.x-tee.ee/catalogue/EE/wsdls/',
'ee-test': 'https://www.x-tee.ee/catalogue/ee-test/wsdls/',
'ee-dev': 'https://www.x-tee.ee/catalogue/ee-dev/wsdls/'
}
const API_SERVICE = 'index.json';
import { MAX_LIMIT, DEFAULT_LIMIT, INSTANCES, API_SERVICE } from './config'
@Injectable({
providedIn: 'root'
})
export class MethodsService {
export class SubsystemsService {
private apiUrlBase = '';
private limit: number = 10;
private offset: number = 0;
private limit: number = DEFAULT_LIMIT;
private nonEmpty: boolean = false;
private filter: string = "";
private subsystems: Subsystem[] = [];
private loadingDone: boolean = false;
private loadingError: boolean = false;
private filter: string = '';
private instance: string = '';
private instanceData = new Object();
subsystemsSubject: BehaviorSubject<Subsystem[]> = new BehaviorSubject([]);
filteredSubsystemsSubject: BehaviorSubject<Subsystem[]> = new BehaviorSubject([]);
@Output() subsystemsUpdated: EventEmitter<any> = new EventEmitter();
@Output() warnings: EventEmitter<string> = new EventEmitter();
constructor(private http: HttpClient) {}
private signalRefresh() {
this.subsystemsUpdated.emit(null);
}
private filteredSubsystems(): Subsystem[] {
let filtered: Subsystem[] = []
let limit: number = this.limit
for (let subsystem of this.subsystems) {
for (let subsystem of this.subsystemsSubject.value) {
if (this.nonEmpty && !subsystem.methods.length) {
// Filtering out empty subsystems
continue
......@@ -66,36 +51,33 @@ export class MethodsService {
// No matching method names found
continue
}
// Copy object to avoid overwriting methods array in subsystem object