Add ability to filter search results by category
This commit is contained in:
parent
72ab2064dd
commit
8c253ac283
@ -7,6 +7,16 @@
|
|||||||
class="search-input"
|
class="search-input"
|
||||||
(ionChange)="onSearchChange($event)"
|
(ionChange)="onSearchChange($event)"
|
||||||
></ion-input>
|
></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>
|
</ion-header>
|
||||||
<div class="search-results" style="height: 100%; overflow-y: scroll;">
|
<div class="search-results" style="height: 100%; overflow-y: scroll;">
|
||||||
<ion-list *ngIf="!loading">
|
<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 {
|
.search-label {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
@ -29,13 +29,36 @@ export class SearchComponent implements OnInit {
|
|||||||
@ViewChild('ionInput') ionInput: IonInput;
|
@ViewChild('ionInput') ionInput: IonInput;
|
||||||
@Input() query = '';
|
@Input() query = '';
|
||||||
public results: BehaviorSubject<SearchResult[]> = new BehaviorSubject<SearchResult[]>([]);
|
public results: BehaviorSubject<SearchResult[]> = new BehaviorSubject<SearchResult[]>([]);
|
||||||
|
public allResults: BehaviorSubject<SearchResult[]> = new BehaviorSubject<SearchResult[]>([]);
|
||||||
public loading = false;
|
public loading = false;
|
||||||
|
|
||||||
public typeIcons = NodeTypeIcons;
|
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) => {
|
protected searchChangeDebounce = debounce(async ($event) => {
|
||||||
const query = $event.detail.value;
|
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;
|
this.loading = false;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
@ -50,6 +73,31 @@ export class SearchComponent implements OnInit {
|
|||||||
await this.ionModalController.dismiss();
|
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() {
|
ngOnInit() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.ionInput.setFocus();
|
this.ionInput.setFocus();
|
||||||
|
Loading…
Reference in New Issue
Block a user