diff --git a/nise-backend/src/main/kotlin/com/nisemoe/nise/search/score/ScoreSearchService.kt b/nise-backend/src/main/kotlin/com/nisemoe/nise/search/score/ScoreSearchService.kt index 64ee443..dfeb354 100644 --- a/nise-backend/src/main/kotlin/com/nisemoe/nise/search/score/ScoreSearchService.kt +++ b/nise-backend/src/main/kotlin/com/nisemoe/nise/search/score/ScoreSearchService.kt @@ -45,6 +45,7 @@ class ScoreSearchService( USERS.COUNT_100, USERS.COUNT_50, USERS.COUNT_MISS, + USERS.IS_BANNED, // Scores fields SCORES.ID, diff --git a/nise-frontend/src/app/api/api.component.html b/nise-frontend/src/app/api/api.component.html index 2779cbb..c915e88 100644 --- a/nise-frontend/src/app/api/api.component.html +++ b/nise-frontend/src/app/api/api.component.html @@ -30,6 +30,18 @@ curl -H "X-NISE-API: 20240218" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"queries":[{"predicates":[{"field":{"name":"user_rank","type":"number"},"operator":{"operatorType":"<","acceptsValues":"any"},"value":"50"},{"field":{"name":"ur","type":"number"},"operator":{"operatorType":"<","acceptsValues":"any"},"value":"120"}],"logicalOperator":"AND"}],"sorting":{"field":"user_id","order":"ASC"},"page":1}' https://nise.moe/api/search +
+ Try it out: +
+ +
@@ -47,6 +59,18 @@ curl -H "X-NISE-API: 20240218" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"queries":[{"predicates":[{"field":{"name":"rank","type":"number"},"operator":{"operatorType":">","acceptsValues":"any"},"value":"10"},{"field":{"name":"username","type":"string"},"operator":{"operatorType":"=","acceptsValues":"any"},"value":"degenerate"}],"logicalOperator":"AND"}],"sorting":{"field":"user_id","order":"ASC"},"page":1}' https://nise.moe/api/search-user +
+ Try it out: +
+ +
@@ -61,6 +85,15 @@ curl -H "X-NISE-API: 20240218" -H "Accept: application/json" https://nise.moe/api/score/3808640439 +
+ Try it out: +
+ +
+
@@ -76,6 +109,14 @@ curl -H "X-NISE-API: 20240218" -H "Accept: application/json" https://nise.moe/api/score/3808640439/replay +
+ Try it out: +
+ +
@@ -104,6 +145,19 @@ curl -X POST -H "X-NISE-API: 20240218" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"userId": 8184689}' https://nise.moe/api/user-details +
+ Try it out: +
+ +
@@ -137,6 +191,13 @@ curl -H "X-NISE-API: 20240218" -H "Accept: application/json" https://nise.moe/api/suspicious-scores +
+ Try it out: +
+ +
@@ -152,6 +213,13 @@ curl -H "X-NISE-API: 20240218" -H "Accept: application/json" https://nise.moe/api/similar-replays +
+ Try it out: +
+ +
@@ -169,6 +237,18 @@ curl -X POST -H "X-NISE-API: 20240218" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"page": 1}' https://nise.moe/api/banlist +
+ Try it out: +
+ +
diff --git a/nise-frontend/src/app/api/api.component.ts b/nise-frontend/src/app/api/api.component.ts index 81b9604..38c2b46 100644 --- a/nise-frontend/src/app/api/api.component.ts +++ b/nise-frontend/src/app/api/api.component.ts @@ -6,6 +6,7 @@ import { CodeWithCopyButtonComponent } from "../../corelib/components/code-with-copy-button/code-with-copy-button.component"; import {RouterLink} from "@angular/router"; +import {ApiTryItComponent} from "../../corelib/components/api-try-it/api-try-it.component"; @Component({ selector: 'app-api', @@ -18,11 +19,15 @@ import {RouterLink} from "@angular/router"; NgForOf, NgIf, CodeWithCopyButtonComponent, - RouterLink + RouterLink, + ApiTryItComponent ], templateUrl: './api.component.html', styleUrl: './api.component.css' }) export class ApiComponent { + placeholderSearchValue = "{\"queries\":[{\"predicates\":[{\"field\":{\"name\":\"user_rank\",\"type\":\"number\"},\"operator\":{\"operatorType\":\"<\",\"acceptsValues\":\"any\"},\"value\":\"50\"},{\"field\":{\"name\":\"ur\",\"type\":\"number\"},\"operator\":{\"operatorType\":\"<\",\"acceptsValues\":\"any\"},\"value\":\"120\"}],\"logicalOperator\":\"AND\"}],\"sorting\":{\"field\":\"user_id\",\"order\":\"ASC\"},\"page\":1}"; + placeholderUserSearchValue = "{\"queries\":[{\"predicates\":[{\"field\":{\"name\":\"rank\",\"type\":\"number\"},\"operator\":{\"operatorType\":\"<\",\"acceptsValues\":\"any\"},\"value\":\"10\"},{\"field\":{\"name\":\"username\",\"type\":\"string\"},\"operator\":{\"operatorType\":\"=\",\"acceptsValues\":\"any\"},\"value\":\"degenerate\"}],\"logicalOperator\":\"AND\"}],\"sorting\":{\"field\":\"user_id\",\"order\":\"ASC\"},\"page\":1}"; + } diff --git a/nise-frontend/src/app/app.component.html b/nise-frontend/src/app/app.component.html index 6bc3181..c1f0f17 100644 --- a/nise-frontend/src/app/app.component.html +++ b/nise-frontend/src/app/app.component.html @@ -11,7 +11,7 @@
  • ./suspicious-scores
  • ./stolen-replays
  • ./advanced-search
  • -
  • ./contribute <3
  • +
  • ./contribute ♥
  • @@ -35,5 +35,5 @@
    - v20240510 + v20240511
    diff --git a/nise-frontend/src/corelib/components/api-try-it/api-try-it.component.css b/nise-frontend/src/corelib/components/api-try-it/api-try-it.component.css new file mode 100644 index 0000000..87ff083 --- /dev/null +++ b/nise-frontend/src/corelib/components/api-try-it/api-try-it.component.css @@ -0,0 +1,4 @@ +pre.response { + max-height: 300px; + overflow: auto; +} diff --git a/nise-frontend/src/corelib/components/api-try-it/api-try-it.component.html b/nise-frontend/src/corelib/components/api-try-it/api-try-it.component.html new file mode 100644 index 0000000..7dd5874 --- /dev/null +++ b/nise-frontend/src/corelib/components/api-try-it/api-try-it.component.html @@ -0,0 +1,22 @@ +
    + +
    + + +
    + + + +
    + Loading 'n' stuff... + +
    + +
    +
    {{ jsonResponse | json }}
    +
    + +
    +

    {{ errorMessage }}

    +
    +
    diff --git a/nise-frontend/src/corelib/components/api-try-it/api-try-it.component.ts b/nise-frontend/src/corelib/components/api-try-it/api-try-it.component.ts new file mode 100644 index 0000000..f72a0db --- /dev/null +++ b/nise-frontend/src/corelib/components/api-try-it/api-try-it.component.ts @@ -0,0 +1,117 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { environment } from '../../../environments/environment'; +import {CuteLoadingComponent} from "../cute-loading/cute-loading.component"; + +@Component({ + selector: 'app-api-try-it', + standalone: true, + imports: [CommonModule, ReactiveFormsModule, CuteLoadingComponent], + templateUrl: './api-try-it.component.html', + styleUrls: ['./api-try-it.component.css'] +}) +export class ApiTryItComponent implements OnInit { + + @Input() apiPath: string = ''; + @Input() placeholderValues: { [key: string]: string } = {}; + @Input() requestType: 'GET' | 'POST' = 'GET'; + @Input() postFieldValues: { title: string, type: 'string' | 'number', required: boolean }[] = []; + + form: FormGroup; + jsonResponse: any; + errorMessage: string | null = null; + isLoading = false; + + constructor(private fb: FormBuilder, private http: HttpClient) { + this.form = this.fb.group({}); + } + + ngOnInit(): void { + this.createForm(); + } + + createForm(): void { + const paramRegex = /\{(\w+)\}/g; + let match; + while ((match = paramRegex.exec(this.apiPath)) !== null) { + const placeholderValue = this.placeholderValues[match[1]] || ''; + this.form.addControl(match[1], this.fb.control(placeholderValue, Validators.required)); + } + + if (this.requestType === 'POST') { + this.postFieldValues.forEach(field => { + const validators = []; + if (field.required) { + validators.push(Validators.required); + } + if (field.type === 'number') { + validators.push(Validators.pattern(/^\d+$/)); + } + const placeholderValue = this.placeholderValues[field.title] || ''; + this.form.addControl(field.title, this.fb.control(placeholderValue, validators)); + }); + } + } + + onSubmit(): void { + this.isLoading = true; + this.jsonResponse = null; // Clear any previous response + let apiUrl = this.apiPath; + Object.keys(this.form.controls).forEach(key => { + apiUrl = apiUrl.replace(`{${key}}`, this.form.get(key)?.value); + }); + const url = `${environment.apiUrl}/${apiUrl}`; + + const headers = new HttpHeaders({ + 'X-NISE-API': '20240218', + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }); + + if (this.requestType === 'GET') { + this.http.get(url, { headers }).subscribe( + response => { + this.jsonResponse = response; + this.errorMessage = null; // Clear any previous error message + this.isLoading = false; + }, + error => { + this.errorMessage = 'There was an error! ' + error.message; + console.error('There was an error!', error); + this.isLoading = false; + } + ); + } else if (this.requestType === 'POST') { + const postData: { [key: string]: any } = {}; + this.postFieldValues.forEach(field => { + const value = this.form.get(field.title)?.value; + if (value !== null && value !== '') { + postData[field.title] = field.type === 'number' ? Number(value) : value; + } + }); + + let body: any; + if (postData.hasOwnProperty('body')) { + body = postData['body']; + } else { + body = postData; + } + + this.http.post(url, body, { headers }).subscribe( + response => { + this.jsonResponse = response; + this.errorMessage = null; // Clear any previous error message + this.isLoading = false; + }, + error => { + this.errorMessage = 'There was an error! ' + error.message; + console.error('There was an error!', error); + this.isLoading = false; + } + ); + } + } +}