diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index ea1b1c6..e10abb1 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -36,6 +36,7 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatCheckboxModule } from '@angular/material/checkbox'; +import {MatGridListModule} from '@angular/material/grid-list'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -100,6 +101,7 @@ export function hljsLanguages() { MatInputModule, MatAutocompleteModule, MatCheckboxModule, + MatGridListModule, HighlightModule.forRoot({ languages: hljsLanguages }) diff --git a/ui/src/app/components/find-object/find-object.component.css b/ui/src/app/components/find-object/find-object.component.css index 8328487..4a8cf93 100644 --- a/ui/src/app/components/find-object/find-object.component.css +++ b/ui/src/app/components/find-object/find-object.component.css @@ -1,3 +1,8 @@ .search-box { width: 300px; } + +.mat-card { + max-height: 400px; + overflow-y: auto; +} diff --git a/ui/src/app/components/find-object/find-object.component.html b/ui/src/app/components/find-object/find-object.component.html index b1ea895..feac065 100644 --- a/ui/src/app/components/find-object/find-object.component.html +++ b/ui/src/app/components/find-object/find-object.component.html @@ -1,25 +1,50 @@ - - - - - - - - - - - - {{res.database}}/{{object.owner}}/{{object.object_type}}/{{object.object_name}} - - - Not found in {{res.database}} - - - - - cancel - + + + + + Search + + + + + + + + + + + + {{res.database}}/{{object.owner}}/{{object.object_type}}/{{object.object_name}} + + + Not found in {{res.database}} + + + + + + + + + cancel + + + + + + + Recent History + + + + + /{{item.endpoint}}/{{item.owner}}/{{item.objectType}}/{{item.objectName}} + + + + + + \ No newline at end of file diff --git a/ui/src/app/components/find-object/find-object.component.ts b/ui/src/app/components/find-object/find-object.component.ts index f6ae8cb..086f195 100644 --- a/ui/src/app/components/find-object/find-object.component.ts +++ b/ui/src/app/components/find-object/find-object.component.ts @@ -15,7 +15,7 @@ */ import { Component, Output, EventEmitter, ElementRef, ViewChild} from '@angular/core'; import { RestService } from 'src/app/services/rest.service'; -import { FindObjectModel } from '../../models/find-object.model'; +import { FindObjectModel, ObjectHistoryModel } from '../../models/find-object.model'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -29,12 +29,14 @@ import { takeUntil } from 'rxjs/operators'; * Quick find feature tied to search icon in toolbar. Finds objects of * a given name in each registered database */ -export class FindObjectComponent { +export class FindObjectComponent { public searchResult: FindObjectModel; + public history: ObjectHistoryModel[] = []; private unsubscribe$ = new Subject(); public searchTerm: string = ''; + public breakpoint: number; - @ViewChild('searchBox') searchBox: ElementRef; + @ViewChild('searchBox') searchBox: ElementRef; @Output() cancelSearchForm: EventEmitter = new EventEmitter(); constructor(private restService: RestService) { @@ -44,14 +46,34 @@ export class FindObjectComponent { this.restService.getSearchResults$(searchTerm) .pipe(takeUntil(this.unsubscribe$)) .subscribe(searchResult => {this.searchResult = searchResult;}); - } - + } + processCancel() { this.cancelSearchForm.emit(false); } + getHistory() { + let localStorageHistory = JSON.parse(localStorage.getItem('objectHistory') || '[]'); + localStorageHistory.forEach((entry) => { + this.history.push(new ObjectHistoryModel + ( entry.endpoint, entry.owner, entry.objectType, entry.objectName, entry.filter)); + }); + } + ngAfterViewInit(): void { + setTimeout(() => this.searchBox.nativeElement.focus()); + this.getHistory(); + } + + /** + * Set the mat-grid-list cols value to 1 if screen width is less than 700px + */ + ngAfterContentInit(): void { + this.breakpoint = (window.innerWidth <= 700) ? 1 : 2; + } + onResize(event) { + this.breakpoint = (event.target.innerWidth <= 700) ? 1 : 2; } ngOnDestroy(): void { diff --git a/ui/src/app/models/find-object.model.ts b/ui/src/app/models/find-object.model.ts index 8c64087..769a079 100644 --- a/ui/src/app/models/find-object.model.ts +++ b/ui/src/app/models/find-object.model.ts @@ -36,7 +36,7 @@ export class FindObjectModel implements Deserializable { export class ResultModel implements Deserializable { public database: string; public objects: ObjectModel[]; - + deserialize(input: any): this { Object.assign(this, input); this.objects = input.objects.map(object => new ObjectModel().deserialize(object)); @@ -51,9 +51,25 @@ export class ObjectModel implements Deserializable { object_name: string; object_type: string; status: string; - + deserialize(input: any): this { Object.assign(this, input); return this; } +} + +export class ObjectHistoryModel { + endpoint: string; + owner: string; + objectType: string; + objectName: string; + filter: string; + + constructor(endpoint: string, owner: string, objectType: string, objectName: string, filter: string){ + this.endpoint = endpoint; + this.owner = owner; + this.objectType = objectType; + this.objectName = objectName; + this.filter = filter; + } } \ No newline at end of file diff --git a/ui/src/app/services/state.service.ts b/ui/src/app/services/state.service.ts index 0109b88..8f53663 100644 --- a/ui/src/app/services/state.service.ts +++ b/ui/src/app/services/state.service.ts @@ -31,7 +31,7 @@ export class StateService { * `currentContext$` holds the menu selection. * The currentContext$ observable records the current menu selection, * the previous selection and a summary of what changed. Subscribers - * use the change summary and previous context to determine whether an API + * use the change summary and previous context to determine whether an API * call is required. */ private _endpoint: string = ''; @@ -49,7 +49,7 @@ export class StateService { new CurrentContextModel('', '', '', '', '', false, []), new CurrentContextModel('', '', '', '', '', false, []), [])); - private sqlEnabled = new BehaviorSubject(false); + private sqlEnabled = new BehaviorSubject(false); endpoints$ = this.endpointList.asObservable(); currentContext$ = this.subjectContext.asObservable(); @@ -82,10 +82,14 @@ export class StateService { this._filter = context.filter; this._showInternal = context.showInternal; this._objectList = context.objectList; + + if (context.objectName){ + this.saveContextInLocalStorage(context); + } } getStoredContext(){ - return new CurrentContextModel(this._endpoint, this._owner, this._objectType, + return new CurrentContextModel(this._endpoint, this._owner, this._objectType, this._objectName, this._filter, this._showInternal, this._objectList); } @@ -104,4 +108,31 @@ export class StateService { this._sqlEnabled = sqlEnabled; this.sqlEnabled.next(sqlEnabled); } + + saveContextInLocalStorage(context: CurrentContextModel) { + const maxHistoryLength = 5; + const contextObject = { "endpoint": context.endpoint, + "owner": context.owner, + "objectType": context.objectType, + "objectName": context.objectName, + "filter": context.filter + }; + + let history = JSON.parse(localStorage.getItem('objectHistory') || '[]'); + let contextObjectPosn = history.findIndex( obj => obj.objectName === contextObject.objectName && + obj.objectType === contextObject.objectType && + obj.owner === contextObject.owner && + obj.endpoint === contextObject.endpoint ); + + if (contextObjectPosn > -1) { + history.splice(contextObjectPosn, 1); + } + if (history.length > maxHistoryLength) { + history = history.slice(1); + } + history.push(contextObject); + localStorage.setItem('objectHistory', JSON.stringify(history)); + } + + }
Not found in {{res.database}}