Fixed <select> flickering
This commit is contained in:
parent
a055e88063
commit
6129257a3b
@ -5,17 +5,24 @@ import {HttpClient} from "@angular/common/http";
|
||||
import {environment} from "../../environments/environment";
|
||||
import {countryCodeToFlag, formatDuration} from "../format";
|
||||
import {OsuGradeComponent} from "../../corelib/components/osu-grade/osu-grade.component";
|
||||
import {Field, Query, QueryBuilderComponent} from "../../corelib/components/query-builder/query-builder.component";
|
||||
import {
|
||||
FieldType,
|
||||
Operator,
|
||||
Query,
|
||||
QueryBuilderComponent
|
||||
} from "../../corelib/components/query-builder/query-builder.component";
|
||||
import {RouterLink} from "@angular/router";
|
||||
import {CalculatePageRangePipe} from "../../corelib/calculate-page-range.pipe";
|
||||
import {DownloadFilesService} from "../../corelib/service/download-files.service";
|
||||
import {CuteLoadingComponent} from "../../corelib/components/cute-loading/cute-loading.component";
|
||||
import {Title} from "@angular/platform-browser";
|
||||
|
||||
export interface SchemaField {
|
||||
name: string;
|
||||
shortName: string;
|
||||
category: 'user' | 'score' | 'beatmap' | 'metrics';
|
||||
type: 'number' | 'string' | 'flag' | 'grade' | 'boolean' | 'datetime' | 'playtime';
|
||||
validOperators: Operator[];
|
||||
active: boolean;
|
||||
description: string;
|
||||
}
|
||||
@ -63,6 +70,7 @@ interface Sorting {
|
||||
export class SearchComponent implements OnInit {
|
||||
|
||||
constructor(private httpClient: HttpClient,
|
||||
private title: Title,
|
||||
public downloadFilesService: DownloadFilesService) { }
|
||||
|
||||
isError = false;
|
||||
@ -76,10 +84,14 @@ export class SearchComponent implements OnInit {
|
||||
queries: Query[] | null = null;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.title.setTitle("/k/ - advanced search");
|
||||
this.isLoadingSchema = true;
|
||||
this.httpClient.get<SchemaResponse>(`${environment.apiUrl}/search/schema`,).subscribe({
|
||||
next: (response) => {
|
||||
this.fields = response.fields;
|
||||
this.fields.forEach(field => {
|
||||
field.validOperators = this.getOperators(field.type);
|
||||
})
|
||||
this.loadPreviousFromLocalStorage();
|
||||
this.isLoadingSchema = false;
|
||||
},
|
||||
@ -89,6 +101,34 @@ export class SearchComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
getOperators(fieldType: FieldType | undefined): Operator[] {
|
||||
switch (fieldType) {
|
||||
case 'number':
|
||||
return ['=', '>', '<', '>=', '<=', '!=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'any'}) as Operator);
|
||||
case 'string':
|
||||
return ['=', 'contains', 'like']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'any'}) as Operator);
|
||||
case 'boolean':
|
||||
return ['=', '!=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'boolean'}) as Operator);
|
||||
case 'flag':
|
||||
return ['=', '!=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'flag'}) as Operator);
|
||||
case 'grade':
|
||||
return ['=', '!=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'grade'}) as Operator);
|
||||
case 'datetime':
|
||||
return ['before', 'after']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'datetime'}) as Operator);
|
||||
case 'playtime':
|
||||
return ['>', '<', '>=', '<=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'any'}) as Operator);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private loadPreviousFromLocalStorage() {
|
||||
const storedQueries = localStorage.getItem('search_settings');
|
||||
if (storedQueries) {
|
||||
@ -227,6 +267,6 @@ export class SearchComponent implements OnInit {
|
||||
|
||||
protected readonly countryCodeToFlag = countryCodeToFlag;
|
||||
protected readonly Math = Math;
|
||||
|
||||
protected readonly formatDuration = formatDuration;
|
||||
|
||||
}
|
||||
|
||||
@ -8,13 +8,8 @@ export type FieldType = 'number' | 'string' | 'flag' | 'grade' | 'boolean' | 'da
|
||||
export type OperatorType = '=' | '>' | '<' | 'contains' | 'like' | '>=' | '<=' | '!=';
|
||||
export type ValueType = 'any' | 'boolean' | 'flag' | 'grade' | 'datetime';
|
||||
|
||||
export interface Field {
|
||||
name: string;
|
||||
type: FieldType;
|
||||
}
|
||||
|
||||
export interface Predicate {
|
||||
field: Field | null;
|
||||
field: SchemaField | null;
|
||||
operator: Operator | null;
|
||||
value: string | number | null;
|
||||
}
|
||||
@ -27,7 +22,7 @@ export interface Operator {
|
||||
export interface Query {
|
||||
predicates: Predicate[];
|
||||
logicalOperator: 'AND' | 'OR';
|
||||
childQueries?: Query[]; // Optional property for sub-queries
|
||||
childQueries?: Query[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
|
||||
|
||||
<select [disabled]="!predicate.field">
|
||||
<option *ngFor="let operator of getOperators(predicate.field?.type)"
|
||||
<option *ngFor="let operator of predicate.field?.validOperators"
|
||||
[selected]="operator.operatorType === predicate.operator?.operatorType"
|
||||
(click)="predicate.operator = operator; this.queryChanged.emit()">
|
||||
{{ operator.operatorType }}
|
||||
|
||||
@ -32,35 +32,7 @@ export class QueryComponent {
|
||||
|
||||
onFieldChange(predicate: Predicate, selectedField: any): void {
|
||||
predicate.field = selectedField;
|
||||
predicate.operator = this.getOperators(selectedField.type)[0];
|
||||
}
|
||||
|
||||
getOperators(fieldType: FieldType | undefined): Operator[] {
|
||||
switch (fieldType) {
|
||||
case 'number':
|
||||
return ['=', '>', '<', '>=', '<=', '!=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'any'}) as Operator);
|
||||
case 'string':
|
||||
return ['=', 'contains', 'like']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'any'}) as Operator);
|
||||
case 'boolean':
|
||||
return ['=', '!=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'boolean'}) as Operator);
|
||||
case 'flag':
|
||||
return ['=', '!=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'flag'}) as Operator);
|
||||
case 'grade':
|
||||
return ['=', '!=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'grade'}) as Operator);
|
||||
case 'datetime':
|
||||
return ['before', 'after']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'datetime'}) as Operator);
|
||||
case 'playtime':
|
||||
return ['>', '<', '>=', '<=']
|
||||
.map((operatorType: String) => ({operatorType: operatorType, acceptsValues: 'any'}) as Operator);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
predicate.operator = selectedField.validOperators[0];
|
||||
}
|
||||
|
||||
addPredicate(): void {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user