mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 17:46:28 +08:00
ui: problemconfig: add testlib builtin checkers
This commit is contained in:
3 files changed
+54
-9
No files matched your search
@@ -1,5 +1,11 @@
|
|||||||
import type { JSONSchema7 } from 'json-schema';
|
import type { JSONSchema7 } from 'json-schema';
|
||||||
|
|
||||||
|
export const testlibCheckers = [
|
||||||
|
'acmp', 'caseicmp', 'casencmp', 'casewcmp', 'dcmp', 'fcmp', 'hcmp',
|
||||||
|
'icmp', 'lcmp', 'ncmp', 'nyesno', 'pointscmp', 'pointsinfo',
|
||||||
|
'rcmp', 'rcmp4', 'rcmp6', 'rcmp9', 'rncmp', 'uncmp', 'wcmp', 'yesno',
|
||||||
|
];
|
||||||
|
|
||||||
const problemConfigSchema: JSONSchema7 = {
|
const problemConfigSchema: JSONSchema7 = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
definitions: {
|
definitions: {
|
||||||
@@ -43,7 +49,12 @@ const problemConfigSchema: JSONSchema7 = {
|
|||||||
langs: { type: 'array', items: { type: 'string' } },
|
langs: { type: 'array', items: { type: 'string' } },
|
||||||
target: { type: 'string' },
|
target: { type: 'string' },
|
||||||
checker_type: { enum: ['default', 'lemon', 'syzoj', 'hustoj', 'testlib', 'strict', 'qduoj'] },
|
checker_type: { enum: ['default', 'lemon', 'syzoj', 'hustoj', 'testlib', 'strict', 'qduoj'] },
|
||||||
checker: { type: 'string', pattern: '\\.' },
|
checker: {
|
||||||
|
oneOf: [
|
||||||
|
{ type: 'string', pattern: '\\.' },
|
||||||
|
{ type: 'string', enum: testlibCheckers },
|
||||||
|
],
|
||||||
|
},
|
||||||
interactor: { type: 'string', pattern: '\\.' },
|
interactor: { type: 'string', pattern: '\\.' },
|
||||||
validator: { type: 'string', pattern: '\\.' },
|
validator: { type: 'string', pattern: '\\.' },
|
||||||
user_extra_files: { type: 'array', items: { type: 'string' } },
|
user_extra_files: { type: 'array', items: { type: 'string' } },
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { i18n } from 'vj/utils';
|
import { i18n } from 'vj/utils';
|
||||||
|
import { testlibCheckers } from '../monaco/schema/problemconfig';
|
||||||
import { FormItem, ManagedSelect, SingleFileSelect } from './BasicForm';
|
import { FormItem, ManagedSelect, SingleFileSelect } from './BasicForm';
|
||||||
import type { RootState } from './reducer/index';
|
import type { RootState } from './reducer/index';
|
||||||
|
|
||||||
@@ -12,6 +13,8 @@ export default function ProblemType() {
|
|||||||
const checkerType = useSelector((state: RootState) => state.config.checker_type);
|
const checkerType = useSelector((state: RootState) => state.config.checker_type);
|
||||||
const filename = useSelector((state: RootState) => state.config.filename);
|
const filename = useSelector((state: RootState) => state.config.filename);
|
||||||
const subType = useSelector((state: RootState) => state.config.subType);
|
const subType = useSelector((state: RootState) => state.config.subType);
|
||||||
|
const checker = useSelector((state: RootState) => state.config.checker);
|
||||||
|
const [category, setCategory] = React.useState(checker?.includes('.') ? 'preset' : 'custom');
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const dispatcher = (base) => (value) => dispatch({ ...base, value });
|
const dispatcher = (base) => (value) => dispatch({ ...base, value });
|
||||||
return (
|
return (
|
||||||
@@ -58,25 +61,56 @@ export default function ProblemType() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{['testlib', 'other'].map((i) => (
|
|
||||||
<Tab
|
<Tab
|
||||||
id={i}
|
id="testlib"
|
||||||
title={i}
|
title="testlib"
|
||||||
key={i}
|
panel={(
|
||||||
|
<div className="row">
|
||||||
|
<FormItem columns={6} label="Type">
|
||||||
|
<select
|
||||||
|
value={category}
|
||||||
|
onChange={(ev) => {
|
||||||
|
setCategory(ev.currentTarget.value);
|
||||||
|
dispatch({ type: 'CONFIG_FORM_UPDATE', key: 'checker', value: null });
|
||||||
|
}}
|
||||||
|
className="select"
|
||||||
|
>
|
||||||
|
<option value="preset">{i18n('Preset')}</option>
|
||||||
|
<option value="custom">{i18n('Custom')}</option>
|
||||||
|
</select>
|
||||||
|
</FormItem>
|
||||||
|
{category === 'preset'
|
||||||
|
? <FormItem columns={6} label="Checker">
|
||||||
|
<select
|
||||||
|
value={checker}
|
||||||
|
onChange={(ev) => dispatch({ type: 'CONFIG_FORM_UPDATE', key: 'checker', value: ev.currentTarget.value })}
|
||||||
|
className="select"
|
||||||
|
>
|
||||||
|
{testlibCheckers.map((c) => (
|
||||||
|
<option key={c} value={c}>{c}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</FormItem>
|
||||||
|
: <FormItem columns={6} label="Checker">
|
||||||
|
<SingleFileSelect formKey="checker" />
|
||||||
|
</FormItem>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Tab
|
||||||
|
id="other"
|
||||||
|
title="other"
|
||||||
panel={(
|
panel={(
|
||||||
<div className="row">
|
<div className="row">
|
||||||
{i === 'other' && (
|
|
||||||
<FormItem columns={6} label="Interface">
|
<FormItem columns={6} label="Interface">
|
||||||
<ManagedSelect options={['syzoj', 'hustoj', 'qduoj', 'lemon']} formKey="checker_type" />
|
<ManagedSelect options={['syzoj', 'hustoj', 'qduoj', 'lemon']} formKey="checker_type" />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
|
||||||
<FormItem columns={6} label="Checker">
|
<FormItem columns={6} label="Checker">
|
||||||
<SingleFileSelect formKey="checker" />
|
<SingleFileSelect formKey="checker" />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
))}
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export default function reducer(state = {
|
|||||||
for (const subtask of subtasks) {
|
for (const subtask of subtasks) {
|
||||||
if (typeof subtask.id !== 'number') {
|
if (typeof subtask.id !== 'number') {
|
||||||
for (let i = 1; ; i++) {
|
for (let i = 1; ; i++) {
|
||||||
if (!subtasks.find((s) => s.id === s)) {
|
if (!subtasks.find((s) => s.id === i)) {
|
||||||
subtask.id = i;
|
subtask.id = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user