ui: drop blueprintjs 6 (#1073)

This commit is contained in:
undefined authored and GitHub committed 2025-11-04 09:08:20 +00:00
1 parent 40114323e4
commit 3996f6f2ef
27 files changed
+764 -652

No files matched your search

@@ -1,10 +1,10 @@
import { TestCaseConfig } from 'hydrooj';
import {
ContextMenu, Menu, MenuItem, TreeNode,
} from '@blueprintjs/core';
import { Text } from '@mantine/core';
import { omit } from 'lodash';
import { useContextMenu } from 'mantine-contextmenu';
import React from 'react';
import { useDrag } from 'react-dnd';
import { useDispatch } from 'react-redux';
import { i18n } from 'vj/utils';
interface TestcaseNodeProps {
@@ -20,37 +20,35 @@ interface TestcaseNodeProps {
export function TestcaseNode(props: TestcaseNodeProps) {
const {
c, selected, onClick, subtaskIds, subtaskId,
c, selected, onClick, subtaskId,
} = props;
let display = `${c.input} / ${c.output}`;
const minlength = Math.min(c.input.length, c.output.length);
for (let i = minlength; i >= 0; i--) {
const prefix = c.input.slice(0, i);
if (c.input.startsWith(prefix) && c.output.startsWith(prefix)) {
display = `${prefix}(${c.input.substring(i)}/${c.output.substring(i)})`;
break;
}
}
return (
<ContextMenu
onContextMenu={onClick}
<div
onClick={onClick}
data-subtaskid={subtaskId}
data-index={c.input}
data-selected={selected}
content={
<Menu>
<MenuItem icon="drawer-left" text={i18n('Move to subtask')}>
{subtaskIds.filter((i) => i !== subtaskId).map((i) => (
<MenuItem key={i} text={i18n('Subtask {0}', i)} />
))}
{subtaskIds.length <= 1 && (
<MenuItem icon="disable" disabled text={i18n('No target available')} />
)}
</MenuItem>
</Menu>
}
style={{
paddingLeft: 22,
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
background: selected ? 'var(--mantine-color-blue-light, #ebf3ff)' : 'transparent',
borderRadius: 4,
fontFamily: 'var(--mantine-font-family-monospace)',
}}
>
<TreeNode
depth={0}
id={c.input}
isSelected={selected}
onClick={onClick}
icon="document"
label={<>&nbsp;{c.input} / {c.output}</>}
path={[0]}
/>
</ContextMenu>
<Text ml="xs"><i className="icon icon-file" /> {display}</Text>
</div>
);
}
@@ -61,8 +59,11 @@ interface TestcaseGroupProps extends Omit<TestcaseNodeProps, 'c'> {
export function TestcaseGroup(props: TestcaseGroupProps) {
const {
cases, subtaskId, onClick, index,
cases, subtaskId, subtaskIds, onClick, index,
} = props;
const dispatch = useDispatch();
const { showContextMenu } = useContextMenu();
const moveTargets = subtaskIds.filter((i) => i !== subtaskId);
const [collected, drag] = useDrag(() => ({
type: 'cases',
collect: (monitor) => ({
@@ -71,7 +72,25 @@ export function TestcaseGroup(props: TestcaseGroupProps) {
canDrag: props.selected,
item: { cases, subtaskId },
}), [JSON.stringify(cases), subtaskId]);
return <div ref={drag} onClick={onClick} onMouseDown={props.onMouseDown} style={{ opacity: collected.isDragging ? 0.5 : 1 }}>
return <div
ref={drag}
onClick={onClick}
onMouseDown={props.onMouseDown}
onContextMenu={showContextMenu(
moveTargets.length
? moveTargets.map((id) => ({
key: `move-${id}`,
icon: <i className="icon icon-send" />,
title: `${i18n('Move to')} ${i18n('Subtask {0}', id)}`,
onClick: () => dispatch({
type: 'problemconfig/moveTestcases',
payload: { target: id, source: subtaskId, cases },
}),
}))
: [{ key: 'no-target', title: i18n('No target available'), onClick: () => { }, disabled: true }],
)}
style={{ opacity: collected.isDragging ? 0.5 : 1 }}
>
{cases.map((c, id) => (
<TestcaseNode c={c} key={`${c.input}@${index + id}`} {...omit(props, 'onClick')} index={index + id} />
))}