update changelog

pull/541/head
undefined 2 years ago
parent 96ddd6721d
commit 3b80564b5c
No known key found for this signature in database

@ -40,6 +40,23 @@ Telegram [@webpack_exports_undefined](https://t.me/webpack_exports_undefined)
<details> <details>
<summary><h2>更新日志(点击展开)</h2></summary> <summary><h2>更新日志(点击展开)</h2></summary>
### Hydro 4.9.0 / UI 4.48.0
- core: 优化讨论鉴权
- judge: 优化统一回调评测状态回显
- judge: 移除 `processTestdata` 步骤
- judge: 客观题子任务分数回显
- core: 压平测试数据结构
- core: rp: 修复比赛分数
- core&ui: 首次使用 OAuth 时要求设置密码
- ui: 评测设置 UI 升级
- install: 根据系统内存调整 wtCacheSize
- ui: 加载速度优化
- core: 检测域 ID 大小写
- ui: 导航栏域索引
- ui: 支持按权限组过滤作业/比赛
- judge: 将 Javascript 默认解释器设置为 node
- judge: 修复删除未评测完成的题目导致评测队列卡死的问题
### Hydro 4.8.0 / UI 4.47.6 ### Hydro 4.8.0 / UI 4.47.6
- core: 升级至 mongodb@5 - core: 升级至 mongodb@5
- ui: 评测详情中显示子任务得分 - ui: 评测详情中显示子任务得分

@ -1,6 +1,6 @@
{ {
"name": "hydrooj", "name": "hydrooj",
"version": "4.9.0", "version": "4.9.1",
"bin": "bin/hydrooj.js", "bin": "bin/hydrooj.js",
"main": "src/plugin-api", "main": "src/plugin-api",
"module": "src/plugin-api", "module": "src/plugin-api",

@ -322,6 +322,11 @@ export class ContestScoreboardHandler extends ContestDetailBaseHandler {
async exportScoreboard(domainId: string, tid: ObjectId, ext: string) { async exportScoreboard(domainId: string, tid: ObjectId, ext: string) {
await this.limitRate('scoreboard_download', 60, 3); await this.limitRate('scoreboard_download', 60, 3);
if (ext === 'ghost') { if (ext === 'ghost') {
if ((contest.isDone(this.tdoc) || contest.isLocked(this.tdoc)) && !this.tdoc.unlocked) {
if (!this.user.own(this.tdoc)) {
this.checkPerm(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD);
}
}
await this.exportGhost(domainId, tid); await this.exportGhost(domainId, tid);
return; return;
} }

@ -1,9 +1,10 @@
import { import {
Button, ControlGroup, Dialog, DialogBody, DialogFooter, Icon, InputGroup, Button, Dialog, DialogBody, DialogFooter, Icon,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { readSubtasksFromFiles } from '@hydrooj/utils/lib/common'; import { readSubtasksFromFiles } from '@hydrooj/utils/lib/common';
import React, { useEffect } from 'react'; import React, { useEffect, useRef } from 'react';
import { useSelector, useStore } from 'react-redux'; import { useSelector, useStore } from 'react-redux';
import FileSelectAutoComplete from '../../autocomplete/components/FileSelectAutoComplete';
import { RootState } from '../reducer'; import { RootState } from '../reducer';
export function AddTestcase() { export function AddTestcase() {
@ -13,9 +14,28 @@ export function AddTestcase() {
const [valid, setValid] = React.useState(false); const [valid, setValid] = React.useState(false);
const testdata = useSelector((state: RootState) => state.testdata); const testdata = useSelector((state: RootState) => state.testdata);
const store = useStore<RootState>(); const store = useStore<RootState>();
const refInput = useRef();
const refOutput = useRef();
useEffect(() => { useEffect(() => {
setValid(testdata.find((i) => i.name === input) && testdata.find((i) => i.name === output)); setValid(testdata.find((i) => i.name === input) && testdata.find((i) => i.name === output));
if (input && !output) {
const filename = input.substring(0, input.lastIndexOf('.'));
let outputFile = '';
if (testdata.find((i) => i.name === `${filename}.out`)) outputFile = `${filename}.out`;
else if (testdata.find((i) => i.name === `${filename}.ans`)) outputFile = `${filename}.ans`;
// @ts-ignore
refOutput.current!.setSelectedItems([outputFile]);
setOutput(outputFile);
}
if (output && !input) {
const filename = output.substring(0, output.lastIndexOf('.'));
if (testdata.find((i) => i.name === `${filename}.in`)) {
// @ts-ignore
refInput.current!.setSelectedItems([`${filename}.in`]);
setInput(`${filename}.in`);
}
}
}, [input, output]); }, [input, output]);
function onConfirm() { function onConfirm() {
@ -57,32 +77,52 @@ export function AddTestcase() {
</li> </li>
<li <li
className="bp4-tree-node" className="bp4-tree-node"
onClick={() => setOpen(true)} onClick={() => {
setInput('');
setOutput('');
setOpen(true);
}}
> >
<div className="bp4-tree-node-content bp4-tree-node-content-0"> <div className="bp4-tree-node-content bp4-tree-node-content-0">
<Icon icon="clean" />&nbsp; <Icon icon="clean" />&nbsp;
<span className="bp4-tree-node-label">Add testcase</span> <span className="bp4-tree-node-label">Add testcase</span>
</div> </div>
</li> </li>
<Dialog title="Add testcasse" icon="cog" isOpen={open} onClose={() => setOpen(false)}> <Dialog title="Add testcase" icon="cog" isOpen={open} onClose={() => setOpen(false)}>
<DialogBody> <DialogBody>
<ControlGroup fill={true} vertical={false}> <div className="row">
{/* TODO: autocomplete */} <div className="columns medium-6">
<InputGroup <FileSelectAutoComplete
leftElement={<Icon icon="import" />} ref={refInput}
onChange={(e) => setInput(e.target.value)} data={testdata}
placeholder="Input" label="Input"
value={input || ''} width="100%"
/> onChange={(e) => setInput(e)}
<InputGroup placeholder="Input"
leftElement={<Icon icon="export" />} value={input || ''}
onChange={(e) => setOutput(e.target.value)} />
placeholder="Output" </div>
value={output || ''} <div className="columns medium-6">
/> <FileSelectAutoComplete
</ControlGroup> ref={refOutput}
data={testdata}
label="Output"
width="100%"
onChange={(e) => setOutput(e)}
placeholder="Output"
value={input || ''}
/>
</div>
</div>
</DialogBody> </DialogBody>
<DialogFooter actions={<Button onClick={onConfirm} disabled={!valid} intent="primary" text="Save" />} /> <DialogFooter actions={
<Button
className={`primary rounded button${valid ? '' : ' disabled'}`}
onClick={onConfirm}
disabled={!valid}
intent="primary"
text="Save"
/>} />
</Dialog> </Dialog>
</>); </>);
} }

@ -65,7 +65,7 @@ export function SubtaskSettings(props: SubtaskSettingsProps) {
/> />
</ControlGroup> </ControlGroup>
</DialogBody> </DialogBody>
<DialogFooter actions={<Button onClick={onConfirm} intent="primary" text="Save" />} /> <DialogFooter actions={<Button className="primary rounded button" onClick={onConfirm} intent="primary" text="Save" />} />
</Dialog> </Dialog>
<li className="bp4-tree-node" onClick={() => setOpen(true)}> <li className="bp4-tree-node" onClick={() => setOpen(true)}>
<div className="bp4-tree-node-content"> <div className="bp4-tree-node-content">
@ -123,7 +123,7 @@ export function GlobalSettings() {
/> />
</ControlGroup> </ControlGroup>
</DialogBody> </DialogBody>
<DialogFooter actions={<Button onClick={onConfirm} intent="primary" text="Save" />} /> <DialogFooter actions={<Button className="primary rounded button" onClick={onConfirm} intent="primary" text="Save" />} />
</Dialog> </Dialog>
<li className="bp4-tree-node" onClick={() => setOpen(true)}> <li className="bp4-tree-node" onClick={() => setOpen(true)}>
<div className="bp4-tree-node-content"> <div className="bp4-tree-node-content">

@ -1,6 +1,6 @@
{ {
"name": "@hydrooj/ui-default", "name": "@hydrooj/ui-default",
"version": "4.48.0", "version": "4.48.1",
"author": "undefined <i@undefined.moe>", "author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "index.ts", "main": "index.ts",

@ -15,6 +15,37 @@
.bp4-tab-panel .bp4-tab-panel
margin-top: 5px margin-top: 5px
.bp4-dialog
font-family: var(--code-font-family)
background: #fff
.autocomplete-container
font-size: 0.875rem
color: #666
.bp4-dialog-footer-fixed
border-top: 0
.button
margin: 0
.bp4-input-group
input
appearance: none
display: block
width: 100%
font-size: 0.875rem
height: 2.1875rem
line-height: 1.2
padding: 0.3125rem;
border: 1px solid #ddd
color: inherit
border-radius: 0
outline: 2px solid transparent
transition: outline-color 0.2s, border-color 0.2s
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1)
box-shadow: none
.problem-config-form .problem-config-form
font-family: var(--code-font-family) font-family: var(--code-font-family)
@ -27,24 +58,6 @@
background: transparent background: transparent
.bp4-input-action .bp4-input-action
pointer-events: none pointer-events: none
.bp4-input-group
input
appearance: none
display: block
width: 100%
font-size: 0.875rem
height: 2.1875rem
line-height: 1.2
padding: 0.3125rem;
border: 1px solid #ddd
color: inherit
border-radius: 0
background-color: transparent
outline: 2px solid transparent
transition: outline-color 0.2s, border-color 0.2s
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1)
box-shadow: none
.data-table .data-table
tr tr

@ -390,3 +390,15 @@ $hover-background-color = #424242
.omnibar-content-section .omnibar-content-section
background-color: $main-background-color !important background-color: $main-background-color !important
border-color: #3d3d3d !important border-color: #3d3d3d !important
.bp4-tab
color: #aaa
&[aria-disabled=true]
color: #555
.bp4-card,.bp4-dialog,.bp4-dialog-header,.bp4-dialog-footer
background-color: #1f1f1f !important
.bp4-input-group input
border-color: #3d3d3d!important

Loading…
Cancel
Save