Skip to content
Snippets Groups Projects
Commit 5c233024 authored by Reid Givens's avatar Reid Givens
Browse files

SSA-6016 make colums sortable

parent 8514af6e
No related branches found
No related tags found
No related merge requests found
Showing
with 245 additions and 18 deletions
......@@ -35,15 +35,30 @@
<input type="text" class="form-control" id="pattern" placeholder="Pattern" formControlName="pattern">
</div>
</form>
<div class="col-auto pl-3"><b>Sort By</b>:</div>
<div class="btn-group col-auto" ngbDropdown>
<button class="btn btn-light btn-sm" type="button" id="sort-select" ngbDropdownToggle>
{{ getPrettyName(filters['JOB_SORT']) }}</button>
<ul ngbDropdownMenu>
<li ngbDropdownItem *ngFor="let col of sortColumns">
<button type="button" class="btn btn-link p-0" (click)="setSortColumn(col)">{{getPrettyName(col)}}</button>
</li>
</ul>
</div>
<div class="btn-group col-auto" ngbDropdown>
<button class="btn btn-light btn-sm" type="button" id="sort-direction" ngbDropdownToggle>
{{ filters['SORT_DIRECTION'] }}</button>
<ul ngbDropdownMenu>
<li ngbDropdownItem *ngFor="let direction of sortDirections">
<button type="button" class="btn btn-link p-0" (click)="setSortDirection(direction)">{{direction}}</button>
</li>
</ul>
</div>
</div>
</div>
<div class="col"></div>
<form class="col-auto form-inline" [formGroup]="alertThresholdForm">
<span class="text-warning ml-4 mr-2"><fa-icon [icon]="faExclamationTriangle"></fa-icon></span>
after <input type="number" min="1" class="form-control form-control-sm mx-2 w-25" formControlName="threshold"/> days
</form>
<div class="col">
<div class="col text-nowrap">
<p class="text-danger text-right p-2 m-0">{{ ((currentPage - 1) * resultsPerPage) + 1 }}
- {{ currentPage * resultsPerPage < numResults ? currentPage * resultsPerPage : numResults}}
of {{ numResults }}</p>
......@@ -75,10 +90,17 @@
</button>
</div>
</div>
</div>
</div>
<div class="row pb-2">
<div class="col"></div>
<form class="col-auto form-inline text-right" [formGroup]="alertThresholdForm">
<span class="text-warning ml-4 mr-2"><fa-icon [icon]="faExclamationTriangle"></fa-icon></span>
after <input type="number" min="1" class="form-control form-control-sm mx-2 w-25" formControlName="threshold"/> days
</form>
</div>
<ng-container *ngIf="jobs; else loading">
<div class="row no-gutters mx-1">
<div class="col-1 px-2 py-3 thead_th">Id</div>
......
......@@ -38,6 +38,8 @@ export class ExecutionsComponent implements OnInit, OnDestroy {
private filters$: Subscription;
public filters: object;
public sortColumns: Array<string>;
public sortDirections: Array<string>;
public faFastBackward = faFastBackward;
public faStepBackward = faStepBackward;
......@@ -59,6 +61,8 @@ export class ExecutionsComponent implements OnInit, OnDestroy {
this.epochs = this.filterService.getFilter('EPOCH');
this.queues = this.filterService.getFilter('JOB_QUEUE');
this.statuses = this.filterService.getFilter('JOB_STATUS');
this.sortColumns = this.filterService.getFilter('JOB_SORT');
this.sortDirections = this.filterService.getFilter('SORT_DIRECTION');
}
ngOnInit() {
......@@ -127,6 +131,18 @@ export class ExecutionsComponent implements OnInit, OnDestroy {
this.filterService.setCurrentSetting('JOB_STATUS', status);
}
setSortColumn(column: string): void {
this.filterService.setCurrentSetting('JOB_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;
......
......@@ -37,6 +37,26 @@
<input type="text" class="form-control" id="pattern" placeholder="Pattern" formControlName="pattern">
</div>
</form>
<div class="col-auto pl-3"><b>Sort By</b>:</div>
<div class="btn-group col-auto" ngbDropdown>
<button class="btn btn-light btn-sm" type="button" id="sort-select" ngbDropdownToggle>
{{ getPrettyName(filters['JOBSPEC_SORT']) }}</button>
<ul ngbDropdownMenu>
<li ngbDropdownItem *ngFor="let col of sortColumns">
<button type="button" class="btn btn-link p-0" (click)="setSortColumn(col)">{{getPrettyName(col)}}</button>
</li>
</ul>
</div>
<div class="btn-group col-auto" ngbDropdown>
<button class="btn btn-light btn-sm" type="button" id="sort-direction" ngbDropdownToggle>
{{ filters['SORT_DIRECTION'] }}</button>
<ul ngbDropdownMenu>
<li ngbDropdownItem *ngFor="let direction of sortDirections">
<button type="button" class="btn btn-link p-0" (click)="setSortDirection(direction)">{{direction}}</button>
</li>
</ul>
</div>
</div>
</div>
......
......@@ -37,6 +37,8 @@ export class JobspecsComponent implements OnInit, OnDestroy {
private filters$: Subscription;
public filters: object;
public sortColumns: Array<string>;
public sortDirections: Array<string>;
public formGroup: FormGroup;
......@@ -64,6 +66,8 @@ export class JobspecsComponent implements OnInit, OnDestroy {
}, error => {
this.canDeleteJobs = false;
});
this.sortColumns = this.filterService.getFilter('JOBSPEC_SORT');
this.sortDirections = this.filterService.getFilter('SORT_DIRECTION');
}
ngOnInit() {
......@@ -103,7 +107,6 @@ export class JobspecsComponent implements OnInit, OnDestroy {
});
this.filters$ = this.filterService.currentSettings$.subscribe((filters: object) => {
console.log('filters');
this.filters = filters;
this.getPageInfoAndJobSpec();
});
......@@ -122,6 +125,18 @@ export class JobspecsComponent implements OnInit, OnDestroy {
this.filterService.setCurrentSetting('JOB_STATUS', status);
}
setSortColumn(column: string): void {
this.filterService.setCurrentSetting('JOBSPEC_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;
......
......@@ -41,6 +41,8 @@ export class Job {
}
}
}
static SORT_COLUMNS = ['id', 'name', 'start_date', 'end_date'];
}
export class Task {
......@@ -94,4 +96,6 @@ export class JobSpec {
sdmId: string;
status: string;
targets: Array<ProductVersion>;
static SORT_COLUMNS = ['id', 'name', 'creation_date'];
}
......@@ -108,4 +108,6 @@ export class Product {
}
}
static SORT_COLUMNS = ['id', 'name', 'status'];
}
......@@ -16,6 +16,8 @@ export class Tile {
raMin: number;
tier: number;
scans: Array<object>;
static SORT_COLUMNS = ['id', 'name', 'status'];
}
export class PhaseCenterDeg {
......
......@@ -23,11 +23,31 @@
</ul>
</div>
<form class="form-inline col pl-4" [formGroup]="formGroup">
<form class="form-inline col-auto pl-4" [formGroup]="formGroup">
<div class="form-group">
<input type="text" class="form-control" id="pattern" placeholder="Pattern/Id" formControlName="pattern">
</div>
</form>
<div class="col-auto pl-3"><b>Sort By</b>:</div>
<div class="btn-group col-auto" ngbDropdown>
<button class="btn btn-light btn-sm" type="button" id="sort-select" ngbDropdownToggle>
{{ getPrettyName(filters['PRODUCT_SORT']) }}</button>
<ul ngbDropdownMenu>
<li ngbDropdownItem *ngFor="let col of sortColumns">
<button type="button" class="btn btn-link p-0" (click)="setSortColumn(col)">{{getPrettyName(col)}}</button>
</li>
</ul>
</div>
<div class="btn-group col-auto" ngbDropdown>
<button class="btn btn-light btn-sm" type="button" id="sort-direction" ngbDropdownToggle>
{{ filters['SORT_DIRECTION'] }}</button>
<ul ngbDropdownMenu>
<li ngbDropdownItem *ngFor="let direction of sortDirections">
<button type="button" class="btn btn-link p-0" (click)="setSortDirection(direction)">{{direction}}</button>
</li>
</ul>
</div>
</div>
</div>
......
......@@ -34,6 +34,8 @@ export class ProductsComponent implements OnInit, OnDestroy {
private filters$: Subscription;
public filters: any;
public sortColumns: Array<string>;
public sortDirections: Array<string>;
private readonly settings$: Subscription;
public canDeleteProducts = false;
......@@ -81,6 +83,8 @@ export class ProductsComponent implements OnInit, OnDestroy {
}, error => {
this.canDeleteProducts = false;
});
this.sortColumns = this.filterService.getFilter('PRODUCT_SORT');
this.sortDirections = this.filterService.getFilter('SORT_DIRECTION');
}
ngOnInit() {
......@@ -162,6 +166,18 @@ export class ProductsComponent implements OnInit, OnDestroy {
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;
......
import {Injectable} from '@angular/core';
import {Product} from "../model/product";
import {Job} from "../model/job";
import {Job, JobSpec} from "../model/job";
import {BehaviorSubject, Observable} from "rxjs";
import {StorageService} from "./storage.service";
import {Epoch} from "../model/epoch";
import {Tile} from "../model/tile";
@Injectable({
......@@ -16,7 +17,12 @@ export class FiltersService {
'PRODUCT_TYPE': Product.TYPES,
'PRODUCT_STATUS': ['ALL', 'COMPLETED', 'WAITING', 'READY', 'COMPLETED', 'PROCESSING', 'CACHED'],
'JOB_QUEUE': Job.QUEUES,
'JOB_STATUS': ['ALL', 'WAITING', 'PROCESSING', 'QA_READY', 'QA_MANUAL', 'QA_ACCEPTED', 'QA_REJECTED', 'QA_ON_HOLD', 'QA_MANUALLY_ACCEPTED', 'ERROR']
'JOB_STATUS': ['ALL', 'WAITING', 'PROCESSING', 'QA_READY', 'QA_MANUAL', 'QA_ACCEPTED', 'QA_REJECTED', 'QA_ON_HOLD', 'QA_MANUAL_ACCEPTED', 'ERROR'],
'SORT_DIRECTION': ['ASC', 'DESC'],
'TILE_SORT': Tile.SORT_COLUMNS,
'PRODUCT_SORT': Product.SORT_COLUMNS,
'JOBSPEC_SORT': JobSpec.SORT_COLUMNS,
'JOB_SORT': Job.SORT_COLUMNS
};
private defaultSettings = {
......@@ -24,7 +30,12 @@ export class FiltersService {
'PRODUCT_TYPE': Product.getTypeFromName('calibration'),
'PRODUCT_STATUS': 'ALL',
'JOB_QUEUE': Job.getQueueFromName('calibration'),
'JOB_STATUS': 'ALL'
'JOB_STATUS': 'ALL',
'SORT_DIRECTION': 'ASC',
'TILE_SORT': 'id',
'PRODUCT_SORT': 'id',
'JOBSPEC_SORT': 'id',
'JOB_SORT': 'id'
};
private currentSettings = {};
......@@ -55,6 +66,15 @@ export class FiltersService {
this._currentSettings.next(this.currentSettings);
}
static prettyName(name: string): string {
if (name.length < 3) {
return name.toUpperCase();
} else {
name = name.replace(/_/g, ' ');
return name.toLowerCase().split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
}
}
getFilters() {
return this.filters
}
......
......@@ -4,6 +4,7 @@ import {ConfigurationService} from "../env/configuration.service";
import {Observable} from "rxjs";
import {map, switchMap} from "rxjs/operators";
import {Job, JobExecution, JobSpec} from "../model/job";
import {FiltersService} from "./filters.service";
@Injectable({
providedIn: 'root'
......@@ -12,7 +13,10 @@ export class JobsService {
endPoint: string = '/services/job/';
constructor(private http: HttpClient, private configService: ConfigurationService) {
constructor(
private http: HttpClient,
private configService: ConfigurationService,
private filtersService: FiltersService) {
}
public getJobRecordCount(epoch: number, queue: string, pattern: string, status: string): Observable<number> {
......@@ -39,6 +43,13 @@ export class JobsService {
if (!!status) {
params = params.append('status', status);
}
const sortName = this.filtersService.getCurrentSetting('JOBSPEC_SORT');
const sortDir = this.filtersService.getCurrentSetting('SORT_DIRECTION');
params = params.append('columnNames', sortName);
params = params.append('directions', sortDir);
return this.http.get<Array<JobSpec>>(this.configService.config.url + this.endPoint + 'specs/byEpoch/' + epoch.toString() + '/byQueue/' + queue +
'/pages/' + pageId.toString() + '/', {params: params, observe: 'response'}).pipe(
map(response => {
......@@ -54,6 +65,13 @@ export class JobsService {
if (!!status) {
params = params.append('status', status);
}
const sortName = this.filtersService.getCurrentSetting('JOB_SORT');
const sortDir = this.filtersService.getCurrentSetting('SORT_DIRECTION');
params = params.append('columnNames', sortName);
params = params.append('directions', sortDir);
return this.http.get<Array<Job>>(this.configService.config.url + this.endPoint + 'byEpoch/' + epoch.toString() + '/byQueue/' + queue +
'/pages/' + pageId.toString() + '/', {params: params, observe: 'response'}).pipe(
map(response => {
......
......@@ -4,6 +4,7 @@ import {ConfigurationService} from "../env/configuration.service";
import {Observable} from "rxjs";
import {map} from "rxjs/operators";
import {Product} from "../model/product";
import {FiltersService} from "./filters.service";
@Injectable({
providedIn: 'root'
......@@ -12,7 +13,10 @@ export class ProductsService {
endPoint: string = '/services/product/';
constructor(private http: HttpClient, private configService: ConfigurationService) {
constructor(
private http: HttpClient,
private configService: ConfigurationService,
private filtersService: FiltersService) {
}
public getRecordCount(epoch: number, type: number, pattern: string): Observable<number> {
......@@ -28,6 +32,13 @@ export class ProductsService {
if (pattern) {
params = params.append('pattern', pattern);
}
const sortName = this.filtersService.getCurrentSetting('PRODUCT_SORT');
const sortDir = this.filtersService.getCurrentSetting('SORT_DIRECTION');
params = params.append('columnNames', sortName);
params = params.append('directions', sortDir);
return this.http.get<Array<Product>>(this.configService.config.url + this.endPoint + 'byEpoch/' + epoch.toString() + '/byType/' + type.toString() +
'/pages/' + pageId.toString() + '/', {params: params, observe: 'response'}).pipe(
map(response => {
......
......@@ -4,6 +4,7 @@ import {Observable} from "rxjs";
import {ConfigurationService} from "../env/configuration.service";
import {map} from "rxjs/operators";
import {Tile, TileDefinition} from "../model/tile";
import {FiltersService} from "./filters.service";
@Injectable({
providedIn: 'root'
......@@ -12,13 +13,21 @@ export class TilesService {
endPoint: string = '/services/minitiles/';
constructor(private configService: ConfigurationService, private http: HttpClient) {
constructor(
private configService: ConfigurationService,
private http: HttpClient,
private filterService: FiltersService) {
}
public getTilesForEpoch(pattern: string, epoch: number): Observable<Array<Tile>> {
let params = new HttpParams();
const sortName = this.filterService.getCurrentSetting('TILE_SORT');
const sortDir = this.filterService.getCurrentSetting('SORT_DIRECTION');
params = params.append('pattern', pattern);
params = params.append('columnNames', sortName);
params = params.append('directions', sortDir);
return this.http.get<Array<Tile>>(this.configService.config.url + this.endPoint + 'summary/epoch/' + epoch.toString(), {
observe: 'response',
......
......@@ -17,8 +17,8 @@
<button type="button" class="btn btn-link p-0" (click)="setEpoch(1)">Epoch 1</button>
</li>
<li ngbDropdownItem>
<button type="button" class="btn btn-link p-0" (click)="setEpoch(2)">Epoch 2</button>
</li>
<button type="button" class="btn btn-link p-0" (click)="setEpoch(2)">Epoch 2</button>
</li>
</ul>
</div>
<form (ngSubmit)="getMinitilesForEpoch()" class="form-inline col-auto pl-4" [formGroup]="formGroup">
......@@ -26,6 +26,26 @@
<input type="text" class="form-control" id="pattern" placeholder="Pattern" formControlName="pattern">
</div>
</form>
<div class="col-auto pl-3"><b>Sort By</b>:</div>
<div class="btn-group col" ngbDropdown>
<button class="btn btn-light btn-sm" type="button" id="sort-select" ngbDropdownToggle>
{{ getPrettyName(filters['TILE_SORT']) }}</button>
<ul ngbDropdownMenu>
<li ngbDropdownItem *ngFor="let col of sortColumns">
<button type="button" class="btn btn-link p-0" (click)="setSortColumn(col)">{{getPrettyName(col)}}</button>
</li>
</ul>
</div>
<div class="btn-group col" ngbDropdown>
<button class="btn btn-light btn-sm" type="button" id="sort-direction" ngbDropdownToggle>
{{ filters['SORT_DIRECTION'] }}</button>
<ul ngbDropdownMenu>
<li ngbDropdownItem *ngFor="let direction of sortDirections">
<button type="button" class="btn btn-link p-0" (click)="setSortDirection(direction)">{{direction}}</button>
</li>
</ul>
</div>
</div>
</div>
<div class="col"></div>
......
......@@ -6,6 +6,7 @@ import {Tile} from "../model/tile";
import {FormControl, FormGroup} from "@angular/forms";
import {AlertService} from "../services/alert.service";
import {faSyncAlt} from "@fortawesome/free-solid-svg-icons";
import {FiltersService} from "../services/filters.service";
@Component({
selector: 'app-tiles',
......@@ -23,7 +24,23 @@ export class TilesComponent implements OnInit, OnDestroy {
public faSyncAlt = faSyncAlt;
constructor(private tileService: TilesService, private alertService: AlertService) {
private readonly filters$: Subscription;
public filters: any;
public sortColumns: Array<string>;
public sortDirections: Array<string>;
constructor(
private tileService: TilesService,
private alertService: AlertService,
private filtersService: FiltersService) {
this.sortColumns = this.filtersService.getFilter('TILE_SORT');
this.sortDirections = this.filtersService.getFilter('SORT_DIRECTION');
this.filters$ = this.filtersService.currentSettings$.subscribe((filters: object) => {
this.filters = filters;
this.getMinitilesForEpoch();
});
}
ngOnInit() {
......@@ -48,6 +65,18 @@ export class TilesComponent implements OnInit, OnDestroy {
this.getMinitilesForEpoch();
}
setSortColumn(column: string): void {
this.filtersService.setCurrentSetting('TILE_SORT', column);
}
setSortDirection(direction: string): void {
this.filtersService.setCurrentSetting('SORT_DIRECTION', direction);
}
getPrettyName(name: string): string {
return FiltersService.prettyName(name);
}
getEpochName(epoch: number): string {
switch (epoch) {
case -1:
......@@ -86,6 +115,9 @@ export class TilesComponent implements OnInit, OnDestroy {
if (this.tiles$) {
this.tiles$.unsubscribe();
}
if (this.filters$) {
this.filters$.unsubscribe();
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment