Skip to content

Commit

Permalink
feat: add admin search job
Browse files Browse the repository at this point in the history
  • Loading branch information
lynzrand committed Sep 26, 2021
1 parent d5660d5 commit 922f5cb
Show file tree
Hide file tree
Showing 15 changed files with 209 additions and 15 deletions.
4 changes: 2 additions & 2 deletions coordinator/Controllers/Admin/AdminTestController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ public class AdminTestController : ControllerBase {
public async Task<IList<Job>> GetJobsFromSuite(
[FromServices] DbService dbService,
[FromRoute] FlowSnake suiteId,
[FromQuery] FlowSnake? startId = null,
[FromQuery] FlowSnake startId = default,
[FromQuery] int take = 20,
[FromQuery] string? user = null,
[FromQuery] bool asc = false) {
FlowSnake? startId_ = startId;
if (startId_ == FlowSnake.MinValue) startId_ = null;
if (startId == default) startId_ = null;
return await dbService.GetJobs(
startId: startId_,
take: take,
Expand Down
2 changes: 1 addition & 1 deletion coordinator/Controllers/TestController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public async Task<IList<Job>> GetJobsFromSuite(
[FromQuery] int take = 20,
[FromQuery] bool asc = false) {
FlowSnake? startId_ = startId;
if (startId_ == FlowSnake.MinValue) startId_ = null;
if (startId == FlowSnake.MinValue) startId_ = null;
var username = AuthHelper.ExtractUsername(HttpContext.User);
return await dbService.GetJobs(
startId: startId_,
Expand Down
9 changes: 8 additions & 1 deletion web/src/components/item-components/item-components.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { RouterModule } from '@angular/router';
import { JobTestItemComponent } from './job-test-item/job-test-item.component';
import { AnnouncementItemComponent } from './announcement-item/announcement-item.component';
import { MarkdownModule } from 'ngx-markdown';
import { IconModule } from '@visurel/iconify-angular';

@NgModule({
declarations: [
Expand All @@ -15,7 +16,13 @@ import { MarkdownModule } from 'ngx-markdown';
JobTestItemComponent,
AnnouncementItemComponent,
],
imports: [CommonModule, BaseComponentsModule, RouterModule, MarkdownModule],
imports: [
CommonModule,
BaseComponentsModule,
RouterModule,
MarkdownModule,
IconModule,
],
exports: [
DashboardItemComponentComponent,
JobItemComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@
<app-slider-view [items]="slider" [height]="8"></app-slider-view>
</div>
</div>
<div class="row text">
<div class="row text" [ngClass]="{ 'show-username': showUsername }">
<div class="id">{{ item.id }}</div>
<div class="repo">{{ item.branch }}</div>
<div class="username" *ngIf="showUsername">
<ic-icon [icon]="userIcon" [inline]="true"></ic-icon> {{ item.account }}
</div>
<div class="repo">
<ic-icon [icon]="branchIcon" [inline]="true"></ic-icon> {{ item.branch }}
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,22 @@
font-variant-numeric: tabular-nums;
}

.username {
font-size: var(--font-size-smaller);
.column(1, 4);
text-align: right;
color: var(--secondary-color);
}

.repo {
font-size: var(--font-size-smaller);
.column(1, 4);
text-align: right;
color: var(--secondary-color);

.show-username & {
text-align: inherit;
}
}

.score {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
import { SliderItem } from 'src/components/base-components/slider-view/slider-view.component';
import { Dayjs } from 'dayjs';
import { TestSuite } from 'src/models/server-types';
import branchIcon from '@iconify/icons-carbon/branch';
import userIcon from '@iconify/icons-carbon/user';

@Component({
selector: 'app-job-item',
Expand All @@ -18,6 +20,10 @@ export class JobItemComponent implements OnInit {
@Input() job: Job;
@Input() testSuite?: TestSuite;
@Input() compact: boolean = false;
@Input() showUsername: boolean = false;

readonly branchIcon = branchIcon;
readonly userIcon = userIcon;

constructor() {}

Expand Down
4 changes: 4 additions & 0 deletions web/src/environments/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ export const endpoints = {
setInitAccount: 'admin/init',
getJudgerStat: 'status/judger',
getCode: 'admin/code',
// TODO: move these paths to /tests/ & update to v2
dumpSuiteJobs: (id: string) => `admin/suite/${id}/dump_jobs`,
dumpSuiteAllJobs: (id: string) => `admin/suite/${id}/dump_all_jobs`,
judgerRegisterToken: 'admin/judger/register-token',
getUserInfo: (username: string) => `admin/user-info/${username}`,
registerUser: `admin/register`,
searchUserInfo: `admin/user-info`,
editPassword: `admin/edit-password`,
testSuite: {
querySuiteJobs: (id: string) => `admin/tests/${id}/jobs`,
},
},
status: {
queue: 'status/job-queue',
Expand Down
2 changes: 2 additions & 0 deletions web/src/models/job-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ interface JobStatus {

export interface JobItem {
id: string;
account: string;
time: Dayjs;
numberBrief: string;
numberBriefSub?: string;
Expand Down Expand Up @@ -194,6 +195,7 @@ const numberFormatter = Intl.NumberFormat('native', {
export function JobToJobItem(job: Job, testSuite?: TestSuite): JobItem {
let res = {
id: job.id,
account: job.account,
numberBrief: resultBriefMain(job, testSuite, numberFormatter),
numberBriefSub: resultBriefSub(job, testSuite, numberFormatter),
status: getStatus(job),
Expand Down
23 changes: 23 additions & 0 deletions web/src/services/api_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ import {

const endpointBase = environment.endpointBase();

export type AdminTestSuiteQueryJobParams = {
startId?: string;
take?: number;
user?: string;
asc?: boolean;
};

@Injectable({ providedIn: 'root' })
export class ApiService {
constructor(private httpClient: HttpClient) {}
Expand Down Expand Up @@ -185,6 +192,22 @@ export class ApiService {
password,
});
},

testSuite: {
querySuiteJobs: (
suiteId: string,
params: AdminTestSuiteQueryJobParams,
take: number,
fromId: string
) => {
return this.httpClient.get<Job[]>(
endpointBase + endpoints.admin.testSuite.querySuiteJobs(suiteId),
{
params: { take, startId: fromId, ...params },
}
);
},
},
};

testSuite = {
Expand Down
5 changes: 5 additions & 0 deletions web/src/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,11 @@ ic-icon {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 0;
flex-shrink: 0;
&.ic-inline {
display: inline;
}
}

.footer {
Expand Down
14 changes: 7 additions & 7 deletions web/src/styles/container.less
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ each(range(1,5),{
display: flex;
flex-direction: row;
align-items: flex-end;
margin-inline-end: calc(-1 * var(--space-1));

& > * {
.margin-x(var(--space-1));

&:first-child {
margin-left: 0;
}
margin-inline-end: var(--space-1);
}

&:last-child {
margin-right: 0;
&.wrap {
flex-wrap: wrap;
& > * {
margin-bottom: var(--space-1);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,46 @@ <h2>导出</h2>
</div>
<div class="section">
<h2>当前结果</h2>
<div class="row wrap col-container">
<textbox
id="test-suite-search-from-user"
caption="来自用户"
[(value)]="searchParams.username"
></textbox>
<textbox
id="test-suite-search-from-id"
caption="起始 ID"
[(value)]="searchParams.startId"
></textbox>
<checkbox
id="test-suite-search-asc"
caption="正序"
[(value)]="searchParams.ascending"
></checkbox>
<button
id="test-suite-search"
class="btn info"
(click)="searchItems()"
[disabled]="searching"
>
搜索
</button>
</div>
<div class="section">
<app-job-item
*ngFor="let item of searchedItems"
[testSuite]="suite"
[job]="item"
[showUsername]="true"
[routerLink]="['/job', item.id]"
></app-job-item>
<button
class="btn secondary dark"
*ngIf="!searching && !searchExhausted && initiatedSearch"
(click)="appendSearch()"
>
加载更多
</button>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
@import "/src/styles/common";

.tag {
font-size: var(--font-size-smaller);
color: var(--secondary-color);
}

.active-above(@theme-breakpoint-md,{
#test-suite-search-from-user{
.column(1,3)
}
#test-suite-search-from-id{
.column(1,3)
}
#test-suite-search-asc{
.column(1,6)
}
#test-suite-search{
.column(1,6,4)
}
});

.active-below(@theme-breakpoint-md,{
#test-suite-search-from-user{
.column(1,2)
}
#test-suite-search-from-id{
.column(1,2)
}
#test-suite-search-asc{
.column(1,2)
}
#test-suite-search{
.column(1,2)
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import {
import { TestSuite } from 'src/models/server-types';
import { environment } from 'src/environments/environment';
import { endpoints } from 'src/environments/endpoints';
import { ApiService } from 'src/services/api_service';
import {
AdminTestSuiteQueryJobParams,
ApiService,
} from 'src/services/api_service';
import { Job, JobItem, JobToJobItem } from 'src/models/job-items';
import { FLOWSNAKE_MIN } from 'src/models/flowsnake';

@Component({
selector: 'app-admin-test-suite-view',
Expand Down Expand Up @@ -116,6 +121,59 @@ export class AdminTestSuiteViewComponent implements OnInit {
});
}

searchParams = {
username: '',
startId: '',
ascending: false,
};
searchedItems: Job[] = [];
largestId: string | undefined = undefined;
searching = false;
searchExhausted = false;
initiatedSearch = false;

searchItems() {
this.initiatedSearch = true;
this.searching = true;
this.searchExhausted = false;
let params: AdminTestSuiteQueryJobParams = this.getSearchParams();
this.api.admin.testSuite
.querySuiteJobs(this.id, params, 50, FLOWSNAKE_MIN)
.subscribe({
next: (v) => {
this.searchedItems = v;
this.searchExhausted = v.length < 50;
this.largestId = v.reduce((p: string | undefined, c) => {
if (c.id > p) return c.id;
else return p;
}, undefined);
},
complete: () => (this.searching = false),
});
}

appendSearch() {
this.searching = true;
let params: AdminTestSuiteQueryJobParams = this.getSearchParams();
this.api.admin.testSuite
.querySuiteJobs(this.id, params, 50, this.largestId ?? FLOWSNAKE_MIN)
.subscribe({
next: (v) => {
this.searchedItems.push(...v);
this.searchExhausted = v.length < 50;
},
complete: () => (this.searching = false),
});
}

private getSearchParams() {
let params: AdminTestSuiteQueryJobParams = {};
if (this.searchParams.username) params.user = this.searchParams.username;
if (this.searchParams.startId) params.startId = this.searchParams.startId;
params.asc = this.searchParams.ascending;
return params;
}

ngOnInit(): void {
this.route.paramMap.subscribe((n) => {
this.id = n.get('id');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ <h1>{{ suite?.title }}</h1>
<div class="lblk">
<div id="job-submit">
<h2>提交评测</h2>
<div class="input-list">
<div class="row col-container">
<textbox
class="repo-input"
type="text"
Expand Down

0 comments on commit 922f5cb

Please sign in to comment.