Add ability to filter search results by category
This commit is contained in:
parent
72ab2064dd
commit
8c253ac283
@ -7,6 +7,16 @@
|
||||
class="search-input"
|
||||
(ionChange)="onSearchChange($event)"
|
||||
></ion-input>
|
||||
<div class="types">
|
||||
<div
|
||||
class="type"
|
||||
*ngFor="let resultType of resultTypes" [ngClass]="(selectedType === resultType ? 'current-type' : '')"
|
||||
(click)="filterView(resultType)"
|
||||
>
|
||||
<i class="assoc-icon" [ngClass]="typeIcons[resultType]" *ngIf="typeIcons[resultType]"></i>
|
||||
{{ typeTitles[resultType] }}
|
||||
</div>
|
||||
</div>
|
||||
</ion-header>
|
||||
<div class="search-results" style="height: 100%; overflow-y: scroll;">
|
||||
<ion-list *ngIf="!loading">
|
||||
|
@ -6,6 +6,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
.types {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.type {
|
||||
padding: 5px 20px;
|
||||
|
||||
&.current-type {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-label {
|
||||
display: flex;
|
||||
|
||||
|
@ -29,13 +29,36 @@ export class SearchComponent implements OnInit {
|
||||
@ViewChild('ionInput') ionInput: IonInput;
|
||||
@Input() query = '';
|
||||
public results: BehaviorSubject<SearchResult[]> = new BehaviorSubject<SearchResult[]>([]);
|
||||
public allResults: BehaviorSubject<SearchResult[]> = new BehaviorSubject<SearchResult[]>([]);
|
||||
public loading = false;
|
||||
|
||||
public typeIcons = NodeTypeIcons;
|
||||
public allResultTypes = ['all', 'page', 'node', 'db', 'code', 'files'];
|
||||
public resultTypes = ['all'];
|
||||
public typeTitles = {
|
||||
all: 'All',
|
||||
page: 'Pages',
|
||||
node: 'Nodes',
|
||||
db: 'Databases',
|
||||
code: 'Code',
|
||||
files: 'Files',
|
||||
};
|
||||
|
||||
public selectedType = 'all';
|
||||
|
||||
protected searchChangeDebounce = debounce(async ($event) => {
|
||||
const query = $event.detail.value;
|
||||
this.results.next(await this.search(query));
|
||||
const results = await this.search(query);
|
||||
this.allResults.next(results);
|
||||
|
||||
if ( !this.allResults.getValue() ) {
|
||||
this.resultTypes = ['all'];
|
||||
} else {
|
||||
const existentTypes = this.allResults.getValue().map(x => this.classifyResult(x));
|
||||
this.resultTypes = this.allResultTypes.filter((x: any) => existentTypes.includes(x) || x === 'all');
|
||||
}
|
||||
|
||||
this.filterView(this.selectedType);
|
||||
this.loading = false;
|
||||
}, 1000);
|
||||
|
||||
@ -50,6 +73,31 @@ export class SearchComponent implements OnInit {
|
||||
await this.ionModalController.dismiss();
|
||||
}
|
||||
|
||||
filterView(name: string) {
|
||||
this.selectedType = name;
|
||||
this.results.next((this.allResults.getValue() || []).filter(x => {
|
||||
if ( this.selectedType === 'all' ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.classifyResult(x) === this.selectedType;
|
||||
}));
|
||||
}
|
||||
|
||||
classifyResult(result: SearchResult) {
|
||||
if ( ['page', 'form'].includes(result.type) ) {
|
||||
return 'page';
|
||||
} else if ( ['node', 'markdown'].includes(result.type) ) {
|
||||
return 'node';
|
||||
} else if ( result.type === 'code' ) {
|
||||
return 'code';
|
||||
} else if ( result.type === 'db' ) {
|
||||
return 'db';
|
||||
} else if ( ['file_box', 'files'].includes(result.type) || result.type.startsWith('file_box') ) {
|
||||
return 'files';
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
setTimeout(() => {
|
||||
this.ionInput.setFocus();
|
||||
|
Loading…
Reference in New Issue
Block a user