mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
ui: bug fix
This commit is contained in:
7 files changed
+33
-49
No files matched your search
@@ -34,7 +34,6 @@ export interface AutoCompleteProps<Item> {
|
||||
allowEmptyQuery?: boolean;
|
||||
freeSolo?: boolean;
|
||||
freeSoloConverter?: (value: string) => string;
|
||||
alwaysShowList?: boolean;
|
||||
}
|
||||
|
||||
export interface AutoCompleteHandle<Item> {
|
||||
@@ -83,22 +82,17 @@ function DraggableSelection({
|
||||
|
||||
// eslint-disable-next-line prefer-arrow-callback
|
||||
const AutoComplete = forwardRef(function Impl<T>(props: AutoCompleteProps<T>, ref: React.Ref<AutoCompleteHandle<T>>) {
|
||||
const width = props.width ?? '100%';
|
||||
const height = props.height ?? 'auto';
|
||||
const disabled = props.disabled ?? false;
|
||||
const disabledHint = props.disabledHint ?? '';
|
||||
const listStyle = props.listStyle ?? {};
|
||||
const {
|
||||
multi = false, width = '100%', height = 'auto',
|
||||
freeSolo = false, allowEmptyQuery = false, listStyle = {},
|
||||
disabled = false, disabledHint = '', draggable = multi,
|
||||
} = props;
|
||||
const queryItems = props.queryItems ?? (() => []);
|
||||
const renderItem = props.renderItem ?? ((item) => item);
|
||||
const itemText = props.itemText ?? ((item) => item.toString());
|
||||
const itemKey = props.itemKey ?? itemText;
|
||||
const onChange = props.onChange ?? (() => { });
|
||||
const multi = props.multi ?? false;
|
||||
const draggable = props.draggable ?? props.multi;
|
||||
const allowEmptyQuery = props.allowEmptyQuery ?? false;
|
||||
const freeSolo = props.freeSolo ?? false;
|
||||
const freeSoloConverter = freeSolo ? props.freeSoloConverter ?? ((i) => i) : ((i) => i);
|
||||
const alwaysShowList = props.alwaysShowList ?? false;
|
||||
|
||||
const [focused, setFocused] = useState(false); // is focused
|
||||
const [selected, setSelected] = useState([]); // selected items
|
||||
@@ -142,6 +136,7 @@ const AutoComplete = forwardRef(function Impl<T>(props: AutoCompleteProps<T>, re
|
||||
useEffect(() => {
|
||||
if (first) first = false;
|
||||
else dispatchChange();
|
||||
if (!multi) return; // Load pre-selected items only in multi mode
|
||||
const ids = [];
|
||||
for (const key of selectedKeys) if (!valueCache[key]) ids.push(key);
|
||||
if (!ids.length) return;
|
||||
@@ -154,7 +149,7 @@ const AutoComplete = forwardRef(function Impl<T>(props: AutoCompleteProps<T>, re
|
||||
const handleInputChange = debounce((e?) => queryList(e ? e.target.value : ''), 300);
|
||||
|
||||
const toggleItem = (item: T, key = itemKey(item), preserve = false) => {
|
||||
const shouldKeepOpen = (multi ? alwaysShowList : allowEmptyQuery) && inputRef.current.value === '';
|
||||
const shouldKeepOpen = multi && allowEmptyQuery && inputRef.current.value === '';
|
||||
if (multi) {
|
||||
const idx = selectedKeys.indexOf(key);
|
||||
if (idx !== -1) {
|
||||
|
||||
@@ -46,7 +46,6 @@ CustomSelectAutoComplete.defaultProps = {
|
||||
selectedKeys: [],
|
||||
freeSolo: false,
|
||||
freeSoloConverter: (input) => input,
|
||||
alwaysShowList: true,
|
||||
};
|
||||
|
||||
export default CustomSelectAutoComplete;
|
||||
@@ -46,7 +46,6 @@ FileSelectAutoComplete.defaultProps = {
|
||||
selectedKeys: [],
|
||||
freeSolo: false,
|
||||
freeSoloConverter: (input) => input,
|
||||
alwaysShowList: true,
|
||||
};
|
||||
|
||||
export default FileSelectAutoComplete;
|
||||
@@ -23,7 +23,7 @@ function FileIOConfig() {
|
||||
rightElement={<Tag minimal>.in/.out</Tag>}
|
||||
value={filename || ''}
|
||||
onChange={(ev) => {
|
||||
dispatch({ type: 'CONFIG_FORM_UPDATE', key: 'filename', value: ev.currentTarget.value });
|
||||
dispatch({ type: 'problemconfig/updateFileIO', filename: ev.currentTarget.value });
|
||||
}}
|
||||
fill
|
||||
/>
|
||||
|
||||
@@ -135,7 +135,7 @@ export function SubtaskConfigTree() {
|
||||
{ids.map((id) => <SubtaskNode key={id} subtaskId={id} />)}
|
||||
<li
|
||||
className="bp4-tree-node"
|
||||
onClick={() => dispatch({ type: 'CONFIG_SUBTASK_UPDATE', id: 0, key: 'add' })}
|
||||
onClick={() => dispatch({ type: 'problemconfig/addSubtask' })}
|
||||
>
|
||||
<div className="bp4-tree-node-content bp4-tree-node-content-0">
|
||||
<Icon icon="folder-new" />
|
||||
|
||||
@@ -15,15 +15,19 @@ const ajv = new Ajv();
|
||||
const validate = ajv.compile(schema);
|
||||
|
||||
export default function reducer(state = {
|
||||
type: 'default', __loaded: false, __valid: true, __errors: [], __cases: [], subtasks: [],
|
||||
type: 'default', __loaded: false, __valid: false, __errors: [], __cases: [], subtasks: [],
|
||||
} as State, action: any = {}): State {
|
||||
switch (action.type) {
|
||||
case 'CONFIG_LOAD_FULFILLED': {
|
||||
const c = { ...state, __loaded: true };
|
||||
try {
|
||||
let data = yaml.load(action.payload.config) as any;
|
||||
if (typeof data !== 'object') data = { subtasks: [] };
|
||||
else data.subtasks ||= [];
|
||||
if (!validate(data)) {
|
||||
return { ...state, __valid: false, __errors: validate.errors.map((i) => `${i.instancePath}: ${i.message}`) };
|
||||
Object.assign(c, data);
|
||||
c.__errors = validate.errors.map((i) => `${i.instancePath}: ${i.message}`);
|
||||
return c;
|
||||
}
|
||||
const subtasks = (data as any).subtasks;
|
||||
for (const subtask of subtasks) {
|
||||
@@ -36,12 +40,12 @@ export default function reducer(state = {
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
...state, ...data as any, __valid: true, __errors: [], __loaded: true,
|
||||
};
|
||||
Object.assign(c, data);
|
||||
c.__valid = true;
|
||||
} catch (e) {
|
||||
return { ...state, __valid: false, __errors: [e.message] };
|
||||
c.__errors.push(e.message);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
case 'CONFIG_FORM_UPDATE': {
|
||||
const next = { ...state, [action.key]: action.value };
|
||||
@@ -94,32 +98,10 @@ export default function reducer(state = {
|
||||
}
|
||||
return next;
|
||||
}
|
||||
case 'CONFIG_SUBTASK_UPDATE': {
|
||||
const subtasks = cloneDeep(state.subtasks);
|
||||
const subtask = state.subtasks.find((i) => i.id === action.id);
|
||||
if (action.value !== '' && ['score', 'id'].includes(action.key)) action.value = +action.value;
|
||||
if (action.key === 'if' && action.value.join('') !== '') action.value = action.value.map((i) => +i);
|
||||
if (action.key.split('-')[0] === 'cases') {
|
||||
if (action.key === 'cases-add') subtask.cases.push(action.value);
|
||||
else if (action.key === 'cases-edit') {
|
||||
if (action.value === '' && !['input', 'output'].includes(action.casesKey)) delete subtask.cases[action.casesId][action.casesKey];
|
||||
else subtask.cases[action.casesId][action.casesKey] = action.value;
|
||||
} else if (action.key === 'cases-delete') {
|
||||
subtask.cases = subtask.cases.filter((k, v) => v !== action.value);
|
||||
}
|
||||
} else if (action.key === 'add') {
|
||||
subtasks.push({
|
||||
cases: [],
|
||||
score: 0,
|
||||
id: Object.keys(subtasks).map((i) => subtasks[i].id).reduce((a, b) => Math.max(+a, +b), 0) + 1,
|
||||
});
|
||||
return { ...state, subtasks };
|
||||
} else if (action.key === 'delete') return { ...state, subtasks: subtasks.filter((k, v) => v !== action.id) };
|
||||
else {
|
||||
if (action.value === '' || (action.key === 'if' && action.value.join('') === '')) delete subtask[action.key];
|
||||
else subtask[action.key] = action.value;
|
||||
}
|
||||
return { ...state, subtasks };
|
||||
case 'problemconfig/updateFileIO': {
|
||||
const n = { ...state, filename: action.filename };
|
||||
if (!n.filename) delete n.filename;
|
||||
return n;
|
||||
}
|
||||
case 'problemconfig/updateGlobalConfig': {
|
||||
const n = { ...state, time: action.time, memory: action.memory };
|
||||
@@ -127,6 +109,15 @@ export default function reducer(state = {
|
||||
if (!n.memory) delete n.memory;
|
||||
return n;
|
||||
}
|
||||
case 'problemconfig/addSubtask': {
|
||||
const subtasks = cloneDeep(state.subtasks);
|
||||
subtasks.push({
|
||||
cases: [],
|
||||
score: 0,
|
||||
id: Object.keys(subtasks).map((i) => subtasks[i].id).reduce((a, b) => Math.max(+a, +b), 0) + 1,
|
||||
});
|
||||
return { ...state, subtasks };
|
||||
}
|
||||
case 'problemconfig/updateSubtaskConfig': {
|
||||
if (!state.subtasks.find((i) => i.id === action.id)) return state;
|
||||
const subtask = { ...state.subtasks.find((i) => i.id === action.id) };
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/ui-default",
|
||||
"version": "4.48.6",
|
||||
"version": "4.48.7",
|
||||
"author": "undefined <i@undefined.moe>",
|
||||
"license": "AGPL-3.0",
|
||||
"main": "index.ts",
|
||||
|
||||
Reference in new issue
Block a user