diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json
index d88a01a8f..b52a5dea5 100644
--- a/packages/hydrooj/package.json
+++ b/packages/hydrooj/package.json
@@ -1,6 +1,6 @@
{
"name": "hydrooj",
- "version": "4.9.2",
+ "version": "4.9.3",
"bin": "bin/hydrooj.js",
"main": "src/plugin-api",
"module": "src/plugin-api",
diff --git a/packages/ui-default/components/problemconfig/SubtaskTable.tsx b/packages/ui-default/components/problemconfig/SubtaskTable.tsx
deleted file mode 100644
index 1a7d49d39..000000000
--- a/packages/ui-default/components/problemconfig/SubtaskTable.tsx
+++ /dev/null
@@ -1,186 +0,0 @@
-import { Card, NumericInput, Tag } from '@blueprintjs/core';
-import { parseMemoryMB, parseTimeMS } from '@hydrooj/utils/lib/common';
-import type { SubtaskConfig } from 'hydrooj/src/interface';
-import { isEqual, pick } from 'lodash';
-import React from 'react';
-import { useDispatch, useSelector } from 'react-redux';
-import { i18n } from 'vj/utils';
-import CustomSelectAutoComplete from '../autocomplete/components/CustomSelectAutoComplete';
-import { FormItem } from './BasicForm';
-import { RootState } from './reducer';
-import { CasesTable } from './TestCasesTable';
-
-const eq = (a: SubtaskConfig, b: SubtaskConfig) => isEqual(a, b);
-
-export function SubtasksIds({ index }) {
- const ids = useSelector((state: RootState) => state.config.subtasks.map((i) => (i ? i.id : undefined)).filter((i) => i !== undefined).join(','));
- const subtaskIf = useSelector((state: RootState) => state.config.subtasks[index].if);
- const dispatch = useDispatch();
- return (
-
- | if |
-
- i.length)}
- selectedKeys={subtaskIf?.map(String) || []}
- onChange={(val) => dispatch({
- type: 'CONFIG_SUBTASK_UPDATE', id: index, key: 'if', value: val.split(','),
- })}
- multi
- />
- |
-
- );
-}
-
-export function SubtasksTable({ index }) {
- const keys = ['id', 'type', 'score', 'time', 'memory'];
- const subtask = useSelector((state: RootState) => pick(state.config.subtasks[index], keys), eq);
- const defaultTime = useSelector((state: RootState) => state.config.time);
- const defaultMemory = useSelector((state: RootState) => state.config.memory);
- const dispatch = useDispatch();
- const dispatcher = (key: string, suffix = '') => (ev: React.ChangeEvent | number) => {
- let value = typeof ev !== 'object' ? ev : ev.currentTarget?.value;
- if (value === 0) value = '';
- if (value && suffix) value += suffix;
- dispatch({
- type: 'CONFIG_SUBTASK_UPDATE', id: index, key, value,
- });
- };
- if (!subtask || Object.keys(subtask).length === 0) {
- return (
-
- Subtasks #{index + 1}
- {i18n('Failed to parse subtask.')}
-
- );
- }
- return (
-
- Subtasks #{index + 1}
- dispatch({ type: 'CONFIG_SUBTASK_UPDATE', id: index, key: 'add' })}>
- dispatch({ type: 'CONFIG_SUBTASK_UPDATE', id: index, key: 'delete' })}
- >
-
-
-
-
-
- );
-}
-
-function GlobalTaskConfig() {
- const time = useSelector((state: RootState) => state.config.time);
- const memory = useSelector((state: RootState) => state.config.memory);
- const dispatch = useDispatch();
- const dispatcher = (key: string, suffix = '') => (ev: React.ChangeEvent | number) => {
- let value = typeof ev !== 'object' ? ev : ev.currentTarget?.value;
- if (value === 0) value = '';
- if (value && suffix) value += suffix;
- dispatch({ type: 'CONFIG_FORM_UPDATE', key, value });
- };
- return (
- <>
-
- ms}
- value={time ? parseTimeMS(time, false).toString() : ''}
- placeholder={parseTimeMS('1000ms').toString()}
- onValueChange={dispatcher('time', 'ms')}
- buttonPosition="none"
- fill
- />
-
-
- MB}
- value={memory ? parseMemoryMB(memory, false).toString() : ''}
- placeholder={parseMemoryMB('256m').toString()}
- onValueChange={dispatcher('memory', 'MB')}
- buttonPosition="none"
- fill
- />
-
- >
- );
-}
-
-export function TaskConfig() {
- const len = useSelector((state: RootState) => state.config.subtasks?.length);
- const dispatch = useDispatch();
- return (
-
-
-
- );
-}
diff --git a/packages/ui-default/components/problemconfig/TestCasesTable.tsx b/packages/ui-default/components/problemconfig/TestCasesTable.tsx
deleted file mode 100644
index 253ad6a7c..000000000
--- a/packages/ui-default/components/problemconfig/TestCasesTable.tsx
+++ /dev/null
@@ -1,162 +0,0 @@
-import { NumericInput, Tag } from '@blueprintjs/core';
-import { parseMemoryMB, parseTimeMS } from '@hydrooj/utils/lib/common';
-import type { SubtaskConfig } from 'hydrooj/src/interface';
-import { isEqual } from 'lodash';
-import React, { useEffect, useRef } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
-import { i18n } from 'vj/utils';
-import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
-import type { RootState } from './reducer/index';
-
-const eq = (a: SubtaskConfig, b: SubtaskConfig) => isEqual(a, b);
-const eqArr = (a: any[], b: any[]) => isEqual(a, b);
-
-export function TestCaseEntry({ index, subindex }) {
- const testcase = useSelector((state: RootState) => state.config.subtasks[index].cases[subindex], eq);
- const Files = useSelector((state: RootState) => state.testdata, eqArr);
- const defaultTime = useSelector((state: RootState) => state.config.subtasks[index].time || state.config.time);
- const defaultMemory = useSelector((state: RootState) => state.config.subtasks[index].memory || state.config.memory);
- const dispatch = useDispatch();
- const dispatcher = (casesKey: string, valueSuffix = '') => (ev: React.ChangeEvent | number) => {
- let value = typeof ev !== 'object' ? ev : ev.currentTarget.value;
- if (value === 0) value = '';
- if (valueSuffix && value) value += valueSuffix;
- dispatch({
- type: 'CONFIG_SUBTASK_UPDATE',
- id: index,
- key: 'cases-edit',
- casesId: subindex,
- casesKey,
- value,
- });
- if ((casesKey === 'input' && (value as string).endsWith('.in') && !testcase.output)
- || (casesKey === 'output' && (value as string).endsWith('.out') && !testcase.input)) {
- const filename = (value as string).substring(0, (value as string).lastIndexOf('.'));
- if (!testcase.output && (Files.map((f) => f.name).includes(`${filename}.out`) || Files.map((f) => f.name).includes(`${filename}.ans`))) {
- dispatch({
- type: 'CONFIG_SUBTASK_UPDATE',
- id: index,
- key: 'cases-edit',
- casesId: subindex,
- casesKey: 'output',
- value: Files.map((f) => f.name).includes(`${filename}.out`) ? `${filename}.out` : `${filename}.ans`,
- });
- }
- if (!testcase.input && Files.map((f) => f.name).includes(`${filename}.in`)) {
- dispatch({
- type: 'CONFIG_SUBTASK_UPDATE',
- id: index,
- key: 'cases-edit',
- casesId: subindex,
- casesKey: 'input',
- value: `${filename}.in`,
- });
- }
- }
- };
- const refs = {
- input: useRef(),
- output: useRef(),
- };
- for (const type of ['input', 'output']) {
- useEffect(() => { // eslint-disable-line
- refs[type].current?.setSelectedItems(testcase[type] ? [testcase[type]] : []);
- }, [testcase[type]]);
- }
- if (!testcase || Object.keys(testcase).length === 0) {
- return (
- | {i18n('Failed to parse testcase.')} |
- );
- }
- return (
-
- |
- ms}
- value={testcase.time ? parseTimeMS(testcase.time, false).toString() : ''}
- placeholder={parseTimeMS(defaultTime || '1000ms', false).toString()}
- onValueChange={dispatcher('time', 'ms')}
- buttonPosition="none"
- fill
- />
- |
-
- MB}
- value={testcase.memory ? parseMemoryMB(testcase.memory, false).toString() : ''}
- placeholder={parseMemoryMB(defaultMemory || '256m', false).toString()}
- onValueChange={dispatcher('memory', 'MB')}
- buttonPosition="none"
- fill
- />
- |
- {['input', 'output'].map((t) => (
-
-
- |
- ))}
-
- dispatch({
- type: 'CONFIG_SUBTASK_UPDATE', id: index, key: 'cases-delete', value: subindex,
- })}
- >
-
- |
-
- );
-}
-
-export function CasesTable({ index }) {
- const len = useSelector((state: RootState) => state.config.subtasks[index].cases?.length);
- const dispatch = useDispatch();
- return (
-
-
-
- | {i18n('Time')} |
- {i18n('Memory')} |
- {i18n('Input')} |
- {i18n('Output')} |
-
- dispatch({
- type: 'CONFIG_SUBTASK_UPDATE',
- id: index,
- key: 'cases-add',
- value: { input: '', output: '' },
- })}
- >
-
- |
-
-
-
-
- | {i18n('Time')} |
- {i18n('Memory')} |
- {i18n('Input')} |
- {i18n('Output')} |
-
- dispatch({
- type: 'CONFIG_SUBTASK_UPDATE',
- id: index,
- key: 'cases-add',
- value: { input: '', output: '' },
- })}
- >
-
- |
-
- {len > 0 && [...Array(len).keys()].map((i) => )}
-
-
- );
-}
diff --git a/packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx b/packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
index f5781a9ae..8caf21aa1 100644
--- a/packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
+++ b/packages/ui-default/components/problemconfig/tree/SubtaskSettings.tsx
@@ -64,15 +64,15 @@ export function SubtaskSettings(props: SubtaskSettingsProps) {
}
rightElement={ms}
- onChange={(ev) => setTime(`${ev.currentTarget.value}ms`)}
- placeholder={`Inherit (${parseTimeMS(props.time, false) || '1000'})`}
+ onChange={(ev) => setTime(ev.currentTarget.value ? `${ev.currentTarget.value}ms` : '')}
+ placeholder={parseTimeMS(props.time, false).toString() || '1000'}
value={ctime ? parseTimeMS(ctime, false).toString() || '' : ''}
/>
}
rightElement={MB}
- onChange={(ev) => setMemory(`${ev.currentTarget.value}MB`)}
- placeholder={`Inherit (${parseMemoryMB(props.memory, false) || '256'})`}
+ onChange={(ev) => setMemory(ev.currentTarget.value ? `${ev.currentTarget.value}MB` : '')}
+ placeholder={parseMemoryMB(props.memory, false).toString() || '256'}
value={cmemory ? parseMemoryMB(cmemory, false).toString() || '' : ''}
/>
}
rightElement={ms}
- onChange={(ev) => setTime(`${ev.currentTarget.value}ms`)}
+ onChange={(ev) => setTime(ev.currentTarget.value ? `${ev.currentTarget.value}ms` : '')}
placeholder="1000"
value={ctime ? parseTimeMS(ctime, false).toString() || '' : ''}
/>
}
rightElement={MB}
- onChange={(ev) => setMemory(`${ev.currentTarget.value}MB`)}
+ onChange={(ev) => setMemory(ev.currentTarget.value ? `${ev.currentTarget.value}MB` : '')}
placeholder="256"
value={cmemory ? parseMemoryMB(cmemory, false).toString() || '' : ''}
/>
diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json
index 6131d5870..8b3e44f1b 100644
--- a/packages/ui-default/package.json
+++ b/packages/ui-default/package.json
@@ -1,6 +1,6 @@
{
"name": "@hydrooj/ui-default",
- "version": "4.48.4",
+ "version": "4.48.5",
"author": "undefined ",
"license": "AGPL-3.0",
"main": "index.ts",