Added handling of flag/grade operators, improved schema loading, fixed bug in search and/or
This commit is contained in:
parent
59a2d0448a
commit
3adeea3094
@ -252,9 +252,6 @@ class SearchController(
|
||||
)
|
||||
}
|
||||
|
||||
// Filter privileged fields
|
||||
|
||||
|
||||
val schema = SearchSchema(fields)
|
||||
return ResponseEntity.ok(schema)
|
||||
}
|
||||
@ -269,7 +266,11 @@ class SearchController(
|
||||
var baseQuery = DSL.noCondition()
|
||||
for (query in request.queries.filter { it.predicates.isNotEmpty() }) {
|
||||
val condition = buildCondition(query)
|
||||
baseQuery = baseQuery.and(condition)
|
||||
baseQuery = when (query.logicalOperator.lowercase()) {
|
||||
"and" -> baseQuery.and(condition)
|
||||
"or" -> baseQuery.or(condition)
|
||||
else -> throw IllegalArgumentException("Invalid logical operator")
|
||||
}
|
||||
}
|
||||
|
||||
val results = dslContext.select(
|
||||
@ -473,6 +474,8 @@ class SearchController(
|
||||
"number" -> buildNumberCondition(field as Field<Double>, predicate.operator.operatorType, predicate.value.toDouble())
|
||||
"string" -> buildStringCondition(field as Field<String>, predicate.operator.operatorType, predicate.value)
|
||||
"boolean" -> buildBooleanCondition(field as Field<Boolean>, predicate.operator.operatorType, predicate.value.toBoolean())
|
||||
"flag" -> buildStringCondition(field as Field<String>, predicate.operator.operatorType, predicate.value)
|
||||
"grade" -> buildGradeCondition(field as Field<String>, predicate.operator.operatorType, predicate.value)
|
||||
else -> throw IllegalArgumentException("Invalid field type")
|
||||
}
|
||||
}
|
||||
@ -550,6 +553,24 @@ class SearchController(
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildGradeCondition(field: Field<String>, operator: String, value: String): Condition {
|
||||
return when (value) {
|
||||
"SS", "S", "A", "B", "C", "D" -> {
|
||||
val valuesToMatch = when (value) {
|
||||
"SS" -> listOf("Grade.SS", "Grade.SSH")
|
||||
"S" -> listOf("Grade.S", "Grade.SH")
|
||||
else -> listOf("Grade.$value")
|
||||
}
|
||||
when (operator) {
|
||||
"=" -> field.`in`(valuesToMatch)
|
||||
"!=" -> field.notIn(valuesToMatch)
|
||||
else -> throw IllegalArgumentException("Invalid operator")
|
||||
}
|
||||
}
|
||||
else -> throw IllegalArgumentException("Invalid grade value")
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildNumberCondition(field: Field<Double>, operator: String, value: Double): Condition {
|
||||
return when (operator) {
|
||||
"=" -> field.eq(value)
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
<form (ngSubmit)="onSubmit()">
|
||||
<input type="text" [(ngModel)]="term" [ngModelOptions]="{standalone: true}" id="nise-osu-username" required minlength="2" maxlength="50" placeholder="Search for users...">
|
||||
</form>
|
||||
<div style="margin-top: 8px">
|
||||
<div style="margin-top: 6px">
|
||||
<ng-container *ngIf="this.userService.isUserLoggedIn()">
|
||||
hi, <span class="user-details" [title]="this.userService.currentUser?.username">{{this.userService.currentUser?.username}}</span> <a [href]="this.userService.getLogoutUrl()">Logout</a>
|
||||
</ng-container>
|
||||
|
||||
@ -1,142 +1,149 @@
|
||||
<div class="main term">
|
||||
<h1><span class="board">/k/</span> - Advanced Search</h1>
|
||||
|
||||
<fieldset>
|
||||
<legend>Table columns</legend>
|
||||
<ng-container *ngFor="let category of ['user', 'beatmap', 'score']">
|
||||
<fieldset class="mb-2">
|
||||
<legend>{{ category }} <button (click)="this.selectEntireFieldCategory(category)">Select all</button> <button (click)="this.deselectEntireFieldCategory(category)">Deselect all</button></legend>
|
||||
<ng-container *ngFor="let field of fields">
|
||||
<div *ngIf="field.category === category">
|
||||
<label>
|
||||
<input type="checkbox" [(ngModel)]="field.active" (change)="this.saveSettingsToLocalStorage()"/>
|
||||
{{ field.name }} <span class="text-muted" style="margin-left: 6px">{{ field.description }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</ng-container>
|
||||
</fieldset>
|
||||
</ng-container>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<div class="search-container mt-2" *ngIf="this.queries">
|
||||
<app-query-builder [queries]="this.queries" [fields]="this.mapSchemaFieldsToFields()"></app-query-builder>
|
||||
</div>
|
||||
|
||||
<fieldset class="mt-2" *ngIf="this.sortingOrder">
|
||||
<legend>sorting</legend>
|
||||
|
||||
<select>
|
||||
<option *ngFor="let field of fields"
|
||||
[value]="field.name"
|
||||
(click)="this.sortingOrder.field = field.name"
|
||||
[selected]="field.name == this.sortingOrder.field"
|
||||
>{{ field.name }}</option>
|
||||
</select>
|
||||
<label>
|
||||
<input type="radio" name="sortingOrder" [(ngModel)]="this.sortingOrder.order" value="ASC" />
|
||||
ASC
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="sortingOrder" [(ngModel)]="this.sortingOrder.order" value="DESC" />
|
||||
DESC
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
<div class="text-center mt-2">
|
||||
<button (click)="exportSettings()">Export settings</button>
|
||||
<button (click)="fileInput.click()" style="margin-left: 5px">Import settings</button>
|
||||
<input type="file" #fileInput style="display: none" (change)="uploadSettingsFile($event)" accept=".json">
|
||||
</div>
|
||||
<div class="text-center mt-1">
|
||||
<button (click)="search()" class="mb-2" style="font-size: 18px">Search</button>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="this.isLoading">
|
||||
<ng-container *ngIf="this.isLoadingSchema; else searchPanel">
|
||||
<div class="text-center">
|
||||
<p>Loading...</p>
|
||||
<p>Loading schema...</p>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-template #searchPanel>
|
||||
<fieldset>
|
||||
<legend>Table columns</legend>
|
||||
<ng-container *ngFor="let category of ['user', 'beatmap', 'score']">
|
||||
<fieldset class="mb-2">
|
||||
<legend>{{ category }} <button (click)="this.selectEntireFieldCategory(category)">Select all</button> <button (click)="this.deselectEntireFieldCategory(category)">Deselect all</button></legend>
|
||||
<ng-container *ngFor="let field of fields">
|
||||
<div *ngIf="field.category === category">
|
||||
<label>
|
||||
<input type="checkbox" [(ngModel)]="field.active" (change)="this.saveSettingsToLocalStorage()"/>
|
||||
{{ field.name }} <span class="text-muted" style="margin-left: 6px">{{ field.description }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</ng-container>
|
||||
</fieldset>
|
||||
</ng-container>
|
||||
|
||||
<div class="text-center alert-error" *ngIf="this.isError">
|
||||
<p>Looks like something went wrong... :(</p>
|
||||
<p>I'll look into what caused the error - but feel free to get in touch.</p>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<ng-container *ngIf="response">
|
||||
<ng-container *ngIf="response.scores.length <= 0">
|
||||
<div class="text-center alert-error">
|
||||
<p>No results for your query - try different parameters.</p>
|
||||
<div class="search-container mt-2" *ngIf="this.queries">
|
||||
<app-query-builder [queries]="this.queries" [fields]="this.mapSchemaFieldsToFields()"></app-query-builder>
|
||||
</div>
|
||||
|
||||
<fieldset class="mt-2" *ngIf="this.sortingOrder">
|
||||
<legend>sorting</legend>
|
||||
|
||||
<select>
|
||||
<option *ngFor="let field of fields"
|
||||
[value]="field.name"
|
||||
(click)="this.sortingOrder.field = field.name"
|
||||
[selected]="field.name == this.sortingOrder.field"
|
||||
>{{ field.name }}</option>
|
||||
</select>
|
||||
<label>
|
||||
<input type="radio" name="sortingOrder" [(ngModel)]="this.sortingOrder.order" value="ASC" />
|
||||
ASC
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="sortingOrder" [(ngModel)]="this.sortingOrder.order" value="DESC" />
|
||||
DESC
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
<div class="text-center mt-2">
|
||||
<button (click)="exportSettings()">Export settings</button>
|
||||
<button (click)="fileInput.click()" style="margin-left: 5px">Import settings</button>
|
||||
<input type="file" #fileInput style="display: none" (change)="uploadSettingsFile($event)" accept=".json">
|
||||
</div>
|
||||
<div class="text-center mt-1">
|
||||
<button (click)="search()" class="mb-2" style="font-size: 18px">Search</button>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="this.isLoading">
|
||||
<div class="text-center">
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="response.scores.length > 0">
|
||||
<fieldset class="mb-2">
|
||||
<legend>tools</legend>
|
||||
<div class="text-center">
|
||||
<button (click)="this.downloadFilesService.downloadCSV(response.scores, getColumns(), 'nise-search')">Download .csv</button>
|
||||
<button (click)="this.downloadFilesService.downloadJSON(response.scores, 'nise-search')">Download .json</button>
|
||||
<button (click)="this.downloadFilesService.downloadXLSX(response.scores, 'nise-search')">Download .xlsx</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="scrollable-table">
|
||||
<table class="table-border">
|
||||
<thead>
|
||||
<tr>
|
||||
<th *ngFor="let column of fields" [hidden]="!column.active" class="text-center">
|
||||
{{ column.shortName }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let entry of response.scores" class="score-entry" [routerLink]="['/s/' + entry.replay_id]">
|
||||
<td *ngFor="let column of fields" [hidden]="!column.active" class="text-center" style="line-height: 32px">
|
||||
<ng-container *ngIf="column.type == 'number'">
|
||||
{{ getValue(entry, column.name) | number }}
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.type == 'flag'">
|
||||
<span class="flag">{{ countryCodeToFlag(getValue(entry, column.name)) }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.type == 'grade'">
|
||||
<app-osu-grade [grade]="getValue(entry, column.name)"></app-osu-grade>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.type == 'boolean'">
|
||||
<ng-container *ngIf="getValue(entry, column.name) == true">
|
||||
✓
|
||||
</ng-container>
|
||||
<ng-container *ngIf="getValue(entry, column.name) == false">
|
||||
✗
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.type == 'string'">
|
||||
{{ getValue(entry, column.name) }}
|
||||
</ng-container>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="text-center alert-error" *ngIf="this.isError">
|
||||
<p>Looks like something went wrong... :(</p>
|
||||
<p>I'll look into what caused the error - but feel free to get in touch.</p>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-2">
|
||||
<p>Total results: {{ response.pagination.totalResults | number }}</p>
|
||||
<p>Page: {{ response.pagination.currentPage | number }} / {{ response.pagination.totalPages | number }}</p>
|
||||
<div class="mb-2">
|
||||
<button *ngIf="response.pagination.currentPage > 5" (click)="this.search(1)" style="margin-right: 5px">1</button>
|
||||
<span *ngIf="response.pagination.currentPage > 6">... </span>
|
||||
<button *ngFor="let page of [].constructor(Math.min(response.pagination.totalPages, 10)) | calculatePageRange:response.pagination.currentPage:response.pagination.totalPages; let i = index"
|
||||
(click)="this.search(page)"
|
||||
[disabled]="page == response.pagination.currentPage"
|
||||
style="margin-right: 5px">
|
||||
{{ page }}
|
||||
</button>
|
||||
<span *ngIf="response.pagination.currentPage < response.pagination.totalPages - 5">... </span>
|
||||
<button *ngIf="response.pagination.currentPage < response.pagination.totalPages - 4" (click)="this.search(response.pagination.totalPages)" style="margin-right: 5px">{{ response.pagination.totalPages }}</button>
|
||||
<ng-container *ngIf="response">
|
||||
<ng-container *ngIf="response.scores.length <= 0">
|
||||
<div class="text-center alert-error">
|
||||
<p>No results for your query - try different parameters.</p>
|
||||
</div>
|
||||
<button (click)="this.search(response.pagination.currentPage - 1)" [disabled]="response.pagination.currentPage == 1">← Previous</button>
|
||||
<button (click)="this.search(response.pagination.currentPage + 1)" [disabled]="response.pagination.currentPage == response.pagination.totalPages" style="margin-left: 5px">Next →</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="response.scores.length > 0">
|
||||
<fieldset class="mb-2">
|
||||
<legend>tools</legend>
|
||||
<div class="text-center">
|
||||
<button (click)="this.downloadFilesService.downloadCSV(response.scores, getColumns(), 'nise-search')">Download .csv</button>
|
||||
<button (click)="this.downloadFilesService.downloadJSON(response.scores, 'nise-search')">Download .json</button>
|
||||
<button (click)="this.downloadFilesService.downloadXLSX(response.scores, 'nise-search')">Download .xlsx</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="scrollable-table">
|
||||
<table class="table-border">
|
||||
<thead>
|
||||
<tr>
|
||||
<th *ngFor="let column of fields" [hidden]="!column.active" class="text-center">
|
||||
{{ column.shortName }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let entry of response.scores" class="score-entry" [routerLink]="['/s/' + entry.replay_id]">
|
||||
<td *ngFor="let column of fields" [hidden]="!column.active" class="text-center" style="line-height: 32px">
|
||||
<ng-container *ngIf="column.type == 'number'">
|
||||
{{ getValue(entry, column.name) | number }}
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.type == 'flag'">
|
||||
<span class="flag">{{ countryCodeToFlag(getValue(entry, column.name)) }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.type == 'grade'">
|
||||
<app-osu-grade [grade]="getValue(entry, column.name)"></app-osu-grade>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.type == 'boolean'">
|
||||
<ng-container *ngIf="getValue(entry, column.name) == true">
|
||||
✓
|
||||
</ng-container>
|
||||
<ng-container *ngIf="getValue(entry, column.name) == false">
|
||||
✗
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.type == 'string'">
|
||||
{{ getValue(entry, column.name) }}
|
||||
</ng-container>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-2">
|
||||
<p>Total results: {{ response.pagination.totalResults | number }}</p>
|
||||
<p>Page: {{ response.pagination.currentPage | number }} / {{ response.pagination.totalPages | number }}</p>
|
||||
<div class="mb-2">
|
||||
<button *ngIf="response.pagination.currentPage > 5" (click)="this.search(1)" style="margin-right: 5px">1</button>
|
||||
<span *ngIf="response.pagination.currentPage > 6">... </span>
|
||||
<button *ngFor="let page of [].constructor(Math.min(response.pagination.totalPages, 10)) | calculatePageRange:response.pagination.currentPage:response.pagination.totalPages; let i = index"
|
||||
(click)="this.search(page)"
|
||||
[disabled]="page == response.pagination.currentPage"
|
||||
style="margin-right: 5px">
|
||||
{{ page }}
|
||||
</button>
|
||||
<span *ngIf="response.pagination.currentPage < response.pagination.totalPages - 5">... </span>
|
||||
<button *ngIf="response.pagination.currentPage < response.pagination.totalPages - 4" (click)="this.search(response.pagination.totalPages)" style="margin-right: 5px">{{ response.pagination.totalPages }}</button>
|
||||
</div>
|
||||
<button (click)="this.search(response.pagination.currentPage - 1)" [disabled]="response.pagination.currentPage == 1">← Previous</button>
|
||||
<button (click)="this.search(response.pagination.currentPage + 1)" [disabled]="response.pagination.currentPage == response.pagination.totalPages" style="margin-left: 5px">Next →</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
|
||||
</div>
|
||||
|
||||
@ -102,6 +102,7 @@ export class SearchComponent implements OnInit {
|
||||
|
||||
isError = false;
|
||||
isLoading = false;
|
||||
isLoadingSchema = true;
|
||||
response: SearchResponse | null = null;
|
||||
|
||||
fields: SchemaField[] = [];
|
||||
@ -110,10 +111,12 @@ export class SearchComponent implements OnInit {
|
||||
queries: Query[] | null = null;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.isLoadingSchema = true;
|
||||
this.httpClient.get<SchemaResponse>(`${environment.apiUrl}/search`,).subscribe({
|
||||
next: (response) => {
|
||||
this.fields = response.fields;
|
||||
this.loadPreviousFromLocalStorage();
|
||||
this.isLoadingSchema = false;
|
||||
},
|
||||
error: () => {
|
||||
alert('Error fetching schema');
|
||||
|
||||
@ -5,7 +5,7 @@ import {QueryComponent} from "../query/query.component";
|
||||
|
||||
export type FieldType = 'number' | 'string' | 'flag' | 'grade' | 'boolean';
|
||||
export type OperatorType = '=' | '>' | '<' | 'contains' | 'like' | '>=' | '<=' | '!=';
|
||||
export type ValueType = 'any' | 'boolean';
|
||||
export type ValueType = 'any' | 'boolean' | 'flag' | 'grade';
|
||||
|
||||
export interface Field {
|
||||
name: string;
|
||||
|
||||
@ -41,6 +41,276 @@
|
||||
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="predicate.operator.acceptsValues == 'flag'">
|
||||
|
||||
<select [(ngModel)]="predicate.value" [disabled]="!predicate.field" (change)="this.queryChanged.emit()" style="max-width: 30%">
|
||||
<option value="AD">AD - Andorra</option>
|
||||
<option value="AE">AE - United Arab Emirates</option>
|
||||
<option value="AF">AF - Afghanistan</option>
|
||||
<option value="AG">AG - Antigua and Barbuda</option>
|
||||
<option value="AI">AI - Anguilla</option>
|
||||
<option value="AL">AL - Albania</option>
|
||||
<option value="AM">AM - Armenia</option>
|
||||
<option value="AO">AO - Angola</option>
|
||||
<option value="AQ">AQ - Antarctica</option>
|
||||
<option value="AR">AR - Argentina</option>
|
||||
<option value="AS">AS - American Samoa</option>
|
||||
<option value="AT">AT - Austria</option>
|
||||
<option value="AU">AU - Australia</option>
|
||||
<option value="AW">AW - Aruba</option>
|
||||
<option value="AX">AX - Åland Islands</option>
|
||||
<option value="AZ">AZ - Azerbaijan</option>
|
||||
<option value="BA">BA - Bosnia and Herzegovina</option>
|
||||
<option value="BB">BB - Barbados</option>
|
||||
<option value="BD">BD - Bangladesh</option>
|
||||
<option value="BE">BE - Belgium</option>
|
||||
<option value="BF">BF - Burkina Faso</option>
|
||||
<option value="BG">BG - Bulgaria</option>
|
||||
<option value="BH">BH - Bahrain</option>
|
||||
<option value="BI">BI - Burundi</option>
|
||||
<option value="BJ">BJ - Benin</option>
|
||||
<option value="BL">BL - Saint Barthélemy</option>
|
||||
<option value="BM">BM - Bermuda</option>
|
||||
<option value="BN">BN - Brunei Darussalam</option>
|
||||
<option value="BO">BO - Bolivia (Plurinational State of)</option>
|
||||
<option value="BQ">BQ - Bonaire, Sint Eustatius and Saba</option>
|
||||
<option value="BR">BR - Brazil</option>
|
||||
<option value="BS">BS - Bahamas</option>
|
||||
<option value="BT">BT - Bhutan</option>
|
||||
<option value="BV">BV - Bouvet Island</option>
|
||||
<option value="BW">BW - Botswana</option>
|
||||
<option value="BY">BY - Belarus</option>
|
||||
<option value="BZ">BZ - Belize</option>
|
||||
<option value="CA">CA - Canada</option>
|
||||
<option value="CC">CC - Cocos (Keeling) Islands</option>
|
||||
<option value="CD">CD - Congo, Democratic Republic of the</option>
|
||||
<option value="CF">CF - Central African Republic</option>
|
||||
<option value="CG">CG - Congo</option>
|
||||
<option value="CH">CH - Switzerland</option>
|
||||
<option value="CI">CI - Côte d'Ivoire</option>
|
||||
<option value="CK">CK - Cook Islands</option>
|
||||
<option value="CL">CL - Chile</option>
|
||||
<option value="CM">CM - Cameroon</option>
|
||||
<option value="CN">CN - China</option>
|
||||
<option value="CO">CO - Colombia</option>
|
||||
<option value="CR">CR - Costa Rica</option>
|
||||
<option value="CU">CU - Cuba</option>
|
||||
<option value="CV">CV - Cabo Verde</option>
|
||||
<option value="CW">CW - Curaçao</option>
|
||||
<option value="CX">CX - Christmas Island</option>
|
||||
<option value="CY">CY - Cyprus</option>
|
||||
<option value="CZ">CZ - Czech Republic</option>
|
||||
<option value="DE">DE - Germany</option>
|
||||
<option value="DJ">DJ - Djibouti</option>
|
||||
<option value="DK">DK - Denmark</option>
|
||||
<option value="DM">DM - Dominica</option>
|
||||
<option value="DO">DO - Dominican Republic</option>
|
||||
<option value="DZ">DZ - Algeria</option>
|
||||
<option value="EC">EC - Ecuador</option>
|
||||
<option value="EE">EE - Estonia</option>
|
||||
<option value="EG">EG - Egypt</option>
|
||||
<option value="EH">EH - Western Sahara</option>
|
||||
<option value="ER">ER - Eritrea</option>
|
||||
<option value="ES">ES - Spain</option>
|
||||
<option value="ET">ET - Ethiopia</option>
|
||||
<option value="FI">FI - Finland</option>
|
||||
<option value="FJ">FJ - Fiji</option>
|
||||
<option value="FK">FK - Falkland Islands (Malvinas)</option>
|
||||
<option value="FM">FM - Micronesia (Federated States of)</option>
|
||||
<option value="FO">FO - Faroe Islands</option>
|
||||
<option value="FR">FR - France</option>
|
||||
<option value="GA">GA - Gabon</option>
|
||||
<option value="GB">GB - United Kingdom of Great Britain and Northern Ireland</option>
|
||||
<option value="GD">GD - Grenada</option>
|
||||
<option value="GE">GE - Georgia</option>
|
||||
<option value="GF">GF - French Guiana</option>
|
||||
<option value="GG">GG - Guernsey</option>
|
||||
<option value="GH">GH - Ghana</option>
|
||||
<option value="GI">GI - Gibraltar</option>
|
||||
<option value="GL">GL - Greenland</option>
|
||||
<option value="GM">GM - Gambia</option>
|
||||
<option value="GN">GN - Guinea</option>
|
||||
<option value="GP">GP - Guadeloupe</option>
|
||||
<option value="GQ">GQ - Equatorial Guinea</option>
|
||||
<option value="GR">GR - Greece</option>
|
||||
<option value="GS">GS - South Georgia and the South Sandwich Islands</option>
|
||||
<option value="GT">GT - Guatemala</option>
|
||||
<option value="GU">GU - Guam</option>
|
||||
<option value="GW">GW - Guinea-Bissau</option>
|
||||
<option value="GY">GY - Guyana</option>
|
||||
<option value="HK">HK - Hong Kong</option>
|
||||
<option value="HM">HM - Heard Island and McDonald Islands</option>
|
||||
<option value="HN">HN - Honduras</option>
|
||||
<option value="HR">HR - Croatia</option>
|
||||
<option value="HT">HT - Haiti</option>
|
||||
<option value="HU">HU - Hungary</option>
|
||||
<option value="ID">ID - Indonesia</option>
|
||||
<option value="IE">IE - Ireland</option>
|
||||
<option value="IL">IL - Israel</option>
|
||||
<option value="IM">IM - Isle of Man</option>
|
||||
<option value="IN">IN - India</option>
|
||||
<option value="IO">IO - British Indian Ocean Territory</option>
|
||||
<option value="IQ">IQ - Iraq</option>
|
||||
<option value="IR">IR - Iran (Islamic Republic of)</option>
|
||||
<option value="IS">IS - Iceland</option>
|
||||
<option value="IT">IT - Italy</option>
|
||||
<option value="JE">JE - Jersey</option>
|
||||
<option value="JM">JM - Jamaica</option>
|
||||
<option value="JO">JO - Jordan</option>
|
||||
<option value="JP">JP - Japan</option>
|
||||
<option value="KE">KE - Kenya</option>
|
||||
<option value="KG">KG - Kyrgyzstan</option>
|
||||
<option value="KH">KH - Cambodia</option>
|
||||
<option value="KI">KI - Kiribati</option>
|
||||
<option value="KM">KM - Comoros</option>
|
||||
<option value="KN">KN - Saint Kitts and Nevis</option>
|
||||
<option value="KP">KP - Korea (Democratic People's Republic of)</option>
|
||||
<option value="KR">KR - Korea, Republic of</option>
|
||||
<option value="KW">KW - Kuwait</option>
|
||||
<option value="KY">KY - Cayman Islands</option>
|
||||
<option value="KZ">KZ - Kazakhstan</option>
|
||||
<option value="LA">LA - Lao People's Democratic Republic</option>
|
||||
<option value="LB">LB - Lebanon</option>
|
||||
<option value="LC">LC - Saint Lucia</option>
|
||||
<option value="LI">LI - Liechtenstein</option>
|
||||
<option value="LK">LK - Sri Lanka</option>
|
||||
<option value="LR">LR - Liberia</option>
|
||||
<option value="LS">LS - Lesotho</option>
|
||||
<option value="LT">LT - Lithuania</option>
|
||||
<option value="LU">LU - Luxembourg</option>
|
||||
<option value="LV">LV - Latvia</option>
|
||||
<option value="LY">LY - Libya</option>
|
||||
<option value="MA">MA - Morocco</option>
|
||||
<option value="MC">MC - Monaco</option>
|
||||
<option value="MD">MD - Moldova, Republic of</option>
|
||||
<option value="ME">ME - Montenegro</option>
|
||||
<option value="MF">MF - Saint Martin (French part)</option>
|
||||
<option value="MG">MG - Madagascar</option>
|
||||
<option value="MH">MH - Marshall Islands</option>
|
||||
<option value="MK">MK - North Macedonia</option>
|
||||
<option value="ML">ML - Mali</option>
|
||||
<option value="MM">MM - Myanmar</option>
|
||||
<option value="MN">MN - Mongolia</option>
|
||||
<option value="MO">MO - Macao</option>
|
||||
<option value="MP">MP - Northern Mariana Islands</option>
|
||||
<option value="MQ">MQ - Martinique</option>
|
||||
<option value="MR">MR - Mauritania</option>
|
||||
<option value="MS">MS - Montserrat</option>
|
||||
<option value="MT">MT - Malta</option>
|
||||
<option value="MU">MU - Mauritius</option>
|
||||
<option value="MV">MV - Maldives</option>
|
||||
<option value="MW">MW - Malawi</option>
|
||||
<option value="MX">MX - Mexico</option>
|
||||
<option value="MY">MY - Malaysia</option>
|
||||
<option value="MZ">MZ - Mozambique</option>
|
||||
<option value="NA">NA - Namibia</option>
|
||||
<option value="NC">NC - New Caledonia</option>
|
||||
<option value="NE">NE - Niger</option>
|
||||
<option value="NF">NF - Norfolk Island</option>
|
||||
<option value="NG">NG - Nigeria</option>
|
||||
<option value="NI">NI - Nicaragua</option>
|
||||
<option value="NL">NL - Netherlands</option>
|
||||
<option value="NO">NO - Norway</option>
|
||||
<option value="NP">NP - Nepal</option>
|
||||
<option value="NR">NR - Nauru</option>
|
||||
<option value="NU">NU - Niue</option>
|
||||
<option value="NZ">NZ - New Zealand</option>
|
||||
<option value="OM">OM - Oman</option>
|
||||
<option value="PA">PA - Panama</option>
|
||||
<option value="PE">PE - Peru</option>
|
||||
<option value="PF">PF - French Polynesia</option>
|
||||
<option value="PG">PG - Papua New Guinea</option>
|
||||
<option value="PH">PH - Philippines</option>
|
||||
<option value="PK">PK - Pakistan</option>
|
||||
<option value="PL">PL - Poland</option>
|
||||
<option value="PM">PM - Saint Pierre and Miquelon</option>
|
||||
<option value="PN">PN - Pitcairn</option>
|
||||
<option value="PR">PR - Puerto Rico</option>
|
||||
<option value="PS">PS - Palestine, State of</option>
|
||||
<option value="PT">PT - Portugal</option>
|
||||
<option value="PW">PW - Palau</option>
|
||||
<option value="PY">PY - Paraguay</option>
|
||||
<option value="QA">QA - Qatar</option>
|
||||
<option value="RE">RE - Réunion</option>
|
||||
<option value="RO">RO - Romania</option>
|
||||
<option value="RS">RS - Serbia</option>
|
||||
<option value="RU">RU - Russian Federation</option>
|
||||
<option value="RW">RW - Rwanda</option>
|
||||
<option value="SA">SA - Saudi Arabia</option>
|
||||
<option value="SB">SB - Solomon Islands</option>
|
||||
<option value="SC">SC - Seychelles</option>
|
||||
<option value="SD">SD - Sudan</option>
|
||||
<option value="SE">SE - Sweden</option>
|
||||
<option value="SG">SG - Singapore</option>
|
||||
<option value="SH">SH - Saint Helena, Ascension and Tristan da Cunha</option>
|
||||
<option value="SI">SI - Slovenia</option>
|
||||
<option value="SJ">SJ - Svalbard and Jan Mayen</option>
|
||||
<option value="SK">SK - Slovakia</option>
|
||||
<option value="SL">SL - Sierra Leone</option>
|
||||
<option value="SM">SM - San Marino</option>
|
||||
<option value="SN">SN - Senegal</option>
|
||||
<option value="SO">SO - Somalia</option>
|
||||
<option value="SR">SR - Suriname</option>
|
||||
<option value="SS">SS - South Sudan</option>
|
||||
<option value="ST">ST - Sao Tome and Principe</option>
|
||||
<option value="SV">SV - El Salvador</option>
|
||||
<option value="SX">SX - Sint Maarten (Dutch part)</option>
|
||||
<option value="SY">SY - Syrian Arab Republic</option>
|
||||
<option value="SZ">SZ - Eswatini</option>
|
||||
<option value="TC">TC - Turks and Caicos Islands</option>
|
||||
<option value="TD">TD - Chad</option>
|
||||
<option value="TF">TF - French Southern Territories</option>
|
||||
<option value="TG">TG - Togo</option>
|
||||
<option value="TH">TH - Thailand</option>
|
||||
<option value="TJ">TJ - Tajikistan</option>
|
||||
<option value="TK">TK - Tokelau</option>
|
||||
<option value="TL">TL - Timor-Leste</option>
|
||||
<option value="TM">TM - Turkmenistan</option>
|
||||
<option value="TN">TN - Tunisia</option>
|
||||
<option value="TO">TO - Tonga</option>
|
||||
<option value="TR">TR - Turkey</option>
|
||||
<option value="TT">TT - Trinidad and Tobago</option>
|
||||
<option value="TV">TV - Tuvalu</option>
|
||||
<option value="TW">TW - Taiwan, Province of China</option>
|
||||
<option value="TZ">TZ - Tanzania, United Republic of</option>
|
||||
<option value="UA">UA - Ukraine</option>
|
||||
<option value="UG">UG - Uganda</option>
|
||||
<option value="UM">UM - United States Minor Outlying Islands</option>
|
||||
<option value="US">US - United States of America</option>
|
||||
<option value="UY">UY - Uruguay</option>
|
||||
<option value="UZ">UZ - Uzbekistan</option>
|
||||
<option value="VA">VA - Holy See</option>
|
||||
<option value="VC">VC - Saint Vincent and the Grenadines</option>
|
||||
<option value="VE">VE - Venezuela (Bolivarian Republic of)</option>
|
||||
<option value="VG">VG - Virgin Islands (British)</option>
|
||||
<option value="VI">VI - Virgin Islands (U.S.)</option>
|
||||
<option value="VN">VN - Viet Nam</option>
|
||||
<option value="VU">VU - Vanuatu</option>
|
||||
<option value="WF">WF - Wallis and Futuna</option>
|
||||
<option value="WS">WS - Samoa</option>
|
||||
<option value="YE">YE - Yemen</option>
|
||||
<option value="YT">YT - Mayotte</option>
|
||||
<option value="ZA">ZA - South Africa</option>
|
||||
<option value="ZM">ZM - Zambia</option>
|
||||
<option value="ZW">ZW - Zimbabwe</option>
|
||||
</select>
|
||||
|
||||
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="predicate.operator.acceptsValues == 'grade'">
|
||||
|
||||
<select [(ngModel)]="predicate.value" [disabled]="!predicate.field" (change)="this.queryChanged.emit()" style="max-width: 30%">
|
||||
<option value="SS">SS</option>
|
||||
<option value="S">S</option>
|
||||
<option value="A">A</option>
|
||||
<option value="B">B</option>
|
||||
<option value="C">C</option>
|
||||
<option value="D">D</option>
|
||||
</select>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
|
||||
<button (click)="removePredicate(i)">X</button>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
import {Field, FieldType, Operator, OperatorType, Predicate, Query} from "../query-builder/query-builder.component";
|
||||
import {Field, FieldType, Operator, Predicate, Query} from "../query-builder/query-builder.component";
|
||||
import {JsonPipe, NgForOf, NgIf} from "@angular/common";
|
||||
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
@ -45,6 +45,12 @@ export class QueryComponent {
|
||||
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);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user