import {Component, OnDestroy, OnInit} from '@angular/core'; import {Subscription} from "rxjs"; import {FormControl, FormGroup, Validators} from "@angular/forms"; import {debounceTime, distinctUntilChanged, map} from "rxjs/operators"; import {ProductsService} from "../services/products.service"; import {Product, ProductType} from "../model/product"; import {ActivatedRoute} from "@angular/router"; import {AlertService} from "../services/alert.service"; import {SchedblocksService} from "../services/schedblocks.service"; import { faFastBackward, faFastForward, faMinus, faPlus, faStepBackward, faStepForward, faSyncAlt } from "@fortawesome/free-solid-svg-icons"; import {FiltersService} from "../services/filters.service"; import {Epoch} from "../model/epoch"; import {Setting} from "../model/setting"; import {SettingsService} from "../services/settings.service"; @Component({ selector: 'app-products', templateUrl: './products.component.html', styleUrls: ['./products.component.scss'] }) export class ProductsComponent implements OnInit, OnDestroy { public epochs: Array<Epoch>; public types: Array<ProductType>; public statuses: Array<string>; public pattern: string = ""; private filters$: Subscription; public filters: any; public sortColumns: Array<string>; public sortDirections: Array<string>; private readonly settings$: Subscription; public canDeleteProducts = false; public showImageDetails: boolean = false; public products: Array<Product> = []; public products$: Subscription; public resultsPerPage: number = 100; public currentPage: number = 1; public numResults: number = 0; public pages: number = 1; private pages$: Subscription; public faSyncAlt = faSyncAlt; public formGroup: FormGroup; showNewForm: boolean = false; productFormGroup: FormGroup; public faPlus = faPlus; public faMinus = faMinus; public faFastBackward = faFastBackward; public faStepBackward = faStepBackward; public faFastForward = faFastForward; public faStepForward = faStepForward; constructor( private schedblockService: SchedblocksService, private productService: ProductsService, private route: ActivatedRoute, private alertService: AlertService, private filterService: FiltersService, private settingsService: SettingsService) { this.epochs = this.filterService.getFilter('EPOCH'); this.types = this.filterService.getFilter('PRODUCT_TYPE'); this.statuses = this.filterService.getFilter('PRODUCT_STATUS'); this.settings$ = this.settingsService.getSettings().subscribe((s: Setting) => { if (s) { this.canDeleteProducts = s.allowProductDeletion; } else { this.canDeleteProducts = false; } }, error => { this.canDeleteProducts = false; }); this.sortColumns = this.filterService.getFilter('PRODUCT_SORT'); this.sortDirections = this.filterService.getFilter('SORT_DIRECTION'); } ngOnInit() { this.productFormGroup = new FormGroup({ epoch: new FormControl(null, Validators.required), sbname: new FormControl(null, {validators: Validators.required, updateOn: "blur"}), sbid: new FormControl(null, [Validators.required, Validators.min(1), Validators.max(999999999)]), minitiles: new FormControl(null, Validators.required) }); this.productFormGroup.get('sbname').valueChanges.subscribe((value: string) => { if (this.productFormGroup.get('minitiles').pristine) { this.productFormGroup.get('minitiles').setValue(value.replace(/\./g, ',')); } }); this.formGroup = new FormGroup({ pattern: new FormControl() }); this.route.queryParams.subscribe(params => { if (params.hasOwnProperty('pattern')) { this.pattern = params.pattern; this.formGroup.get('pattern').setValue(params.pattern); } if (params.hasOwnProperty('type')) { const paramType = Product.getTypeFromName(params.type); if (paramType) { this.filterService.setCurrentSetting('PRODUCT_TYPE', paramType); } } if (params.hasOwnProperty('epoch')) { const paramEpoch = Epoch.getEpochFromId(params.epoch); if (paramEpoch) { this.filterService.setCurrentSetting('EPOCHS', paramEpoch); } } }); this.formGroup.get('pattern').valueChanges.pipe( debounceTime(400), distinctUntilChanged(), map(results => results) ).subscribe((val: string) => { this.pattern = val; this.getPageInfoAndProduct(); }); this.filters$ = this.filterService.currentSettings$.subscribe((filters: object) => { this.filters = filters; for (const allowed of this.generateProductEpochs()) { if (filters['EPOCH'].id === allowed.id) { this.productFormGroup.get('epoch').setValue(filters['EPOCH'].id); } let showTypes = [ 'quicklook', 'se_cont', 'se_coarse_cube_image', 'se_coarse_plane_image', 'se_coarse_plane_I_image', 'se_coarse_plane_Q_image', 'se_coarse_plane_U_image' ]; this.showImageDetails = showTypes.indexOf(filters['PRODUCT_TYPE'].name) > -1; } this.getPageInfoAndProduct(); }); } setEpoch(epoch: Epoch) { this.filterService.setCurrentSetting('EPOCH', epoch); } setType(type: ProductType) { this.filterService.setCurrentSetting('PRODUCT_TYPE', type); } setStatus(status: string) { this.filterService.setCurrentSetting('PRODUCT_STATUS', status); } setSortColumn(column: string): void { this.filterService.setCurrentSetting('PRODUCT_SORT', column); } setSortDirection(direction: string): void { this.filterService.setCurrentSetting('SORT_DIRECTION', direction); } getPrettyName(name: string): string { return FiltersService.prettyName(name); } goToPage(page: number): boolean { if (page < 1) { page = 1; } if (page > this.pages) { page = this.pages; } if (this.currentPage == page) { return false; } this.currentPage = page; this.getProducts(); } getPages(): Array<any> { return new Array(this.pages); } getPageCount(): void { const epoch = this.filterService.getCurrentSetting('EPOCH'); const type = this.filterService.getCurrentSetting('PRODUCT_TYPE'); this.pages$ = this.productService.getRecordCount(epoch.id, type.id, this.pattern).subscribe((productNumber: number) => { this.numResults = productNumber; this.pages = Math.ceil(productNumber / this.resultsPerPage); if (this.currentPage > this.pages) { this.currentPage = this.pages; } if (this.currentPage < 1) { this.currentPage = 1; } this.getProducts(); }); } getProducts(): void { // clear a previous call if (this.products$) { this.products$.unsubscribe(); } this.products = null; const epoch = this.filterService.getCurrentSetting('EPOCH'); const type = this.filterService.getCurrentSetting('PRODUCT_TYPE'); this.alertService.info('Getting ' + type.label); this.products$ = this.productService.getPage(epoch.id, type.id, this.currentPage - 1, this.pattern).subscribe((products: Array<Product>) => { if (products && products.length > 0) { this.alertService.success(type.label + ' loaded.'); this.products = products; } else { this.products = []; this.alertService.error('No ' + type.label + ' found.') } }); } getProductById(id: string): void { // clear a previous call if (this.products$) { this.products$.unsubscribe(); } this.products$ = this.productService.getProductById(id).subscribe((product: Product) => { this.products = [product]; this.numResults = 1; this.pages = 1; this.currentPage = 1; }); } getPageInfoAndProduct(): void { let possible_id = parseInt(this.pattern); if (isNaN(possible_id)) { this.getPageCount(); this.getProducts(); } else { this.getProductById(possible_id.toString()); } } generateProductEpochs(): Array<Epoch> { const allowedEpochs = []; // dont allow epoch1 or pilot for (const e of this.epochs) { if (e.id !== 0 && e.id !== 1) { allowedEpochs.push(e); } } return allowedEpochs; } generateProduct() { this.alertService.info('Generating products...'); if (this.productFormGroup.valid) { this.schedblockService.createSchedblock( this.productEpoch.value, this.productSBname.value, this.productsbId.value, this.productMinitiles.value ).subscribe(response => { this.alertService.success('Products Generated'); this.getProducts(); }, (error) => { this.alertService.error('Product generating failed'); }); } else { this.alertService.error('Invalid values in the form'); console.log(this.productFormGroup.value); } } /** * conveinence getters for the form */ get productEpoch(): FormControl { return this.productFormGroup.get('epoch') as FormControl; } get productSBname(): FormControl { return this.productFormGroup.get('sbname') as FormControl; } get productsbId(): FormControl { return this.productFormGroup.get('sbid') as FormControl; } get productMinitiles(): FormControl { return this.productFormGroup.get('minitiles') as FormControl; } ngOnDestroy(): void { if (this.pages$) { this.pages$.unsubscribe(); } if (this.products$) { this.products$.unsubscribe(); } if (this.filters$) { this.filters$.unsubscribe(); } if (this.settings$) { this.settings$.unsubscribe(); } } }