ui: UI&UX enhance, bug fixes

Co-authored-by: panda <panda_dtdyy@outlook.com>
This commit is contained in:
undefinedandpanda authored and panda committed 2022-05-10 01:55:20 +08:00
1 parent 3f37b02b79
commit 310189bc4d
37 files changed
+1104 -948

No files matched your search

@@ -7,7 +7,9 @@ import yaml from 'js-yaml';
import Notification from 'vj/components/notification';
import Dialog, { ConfirmDialog } from 'vj/components/dialog/index';
import download from 'vj/components/zipDownloader';
import { size, readCasesFromFiles, readSubtasksFromFiles } from '@hydrooj/utils/lib/common';
import {
size, readSubtasksFromFiles, parseTimeMS, parseMemoryMB,
} from '@hydrooj/utils/lib/common';
import tpl from 'vj/utils/tpl';
async function handleSection(ev: JQuery.ClickEvent<Document, undefined, any, any>, type: string) {
@@ -29,10 +31,6 @@ function onBeforeUnload(e) {
e.returnValue = '';
}
function ensureFile(testdata) {
return (file: string) => testdata.filter((i) => i === file)[0];
}
const page = new NamedPage('problem_config', () => {
let reduxStore;
@@ -46,12 +44,12 @@ const page = new NamedPage('problem_config', () => {
const dialog = new Dialog({
$body: `
<div class="file-label" style="text-align: center; margin-bottom: 5px; color: gray; font-size: small;"></div>
<div class="bp3-progress-bar bp3-intent-primary bp3-no-stripes">
<div class="file-progress bp3-progress-meter" style="width: 0"></div>
<div class="bp4-progress-bar bp4-intent-primary bp4-no-stripes">
<div class="file-progress bp4-progress-meter" style="width: 0"></div>
</div>
<div class="upload-label" style="text-align: center; margin: 5px 0; color: gray; font-size: small;"></div>
<div class="bp3-progress-bar bp3-intent-primary bp3-no-stripes">
<div class="upload-progress bp3-progress-meter" style="width: 0"></div>
<div class="bp4-progress-bar bp4-intent-primary bp4-no-stripes">
<div class="upload-progress bp4-progress-meter" style="width: 0"></div>
</div>`,
});
try {
@@ -147,7 +145,7 @@ const page = new NamedPage('problem_config', () => {
await download(`${pdoc.docId} ${pdoc.title}.zip`, targets);
}
async function uploadConfig(config:object) {
async function uploadConfig(config: object) {
const configYaml = yaml.dump(config);
Notification.info(i18n('Saving file...'));
const data = new FormData();
@@ -161,9 +159,11 @@ const page = new NamedPage('problem_config', () => {
}
async function mountComponent() {
const { default: ProblemConfigEditor } = await import('vj/components/problemconfig/ProblemConfigEditor');
const { default: ProblemConfigForm } = await import('vj/components/problemconfig/ProblemConfigForm');
const { default: ProblemConfigReducer } = await import('vj/components/problemconfig/reducer');
const [{ default: ProblemConfigEditor }, { default: ProblemConfigForm }, { default: ProblemConfigReducer }] = await Promise.all([
import('vj/components/problemconfig/ProblemConfigEditor'),
import('vj/components/problemconfig/ProblemConfigForm'),
import('vj/components/problemconfig/reducer'),
]);
const {
React, render, Provider, store,
@@ -175,6 +175,26 @@ const page = new NamedPage('problem_config', () => {
type: 'CONFIG_LOAD',
payload: request.get(),
});
const unsubscribe = store.subscribe(() => {
// TODO set yaml schema
const state = store.getState();
if (!state.config.__loaded) return;
if (state.config.subtasks || state.config.cases) return;
const testdata = (state.testdata || []).map((i) => i.name);
const checkFile = (file: string) => (testdata.includes(file) ? file : null);
unsubscribe();
const value = readSubtasksFromFiles(testdata, checkFile, state.config, {});
for (const subtask of value.subtasks) {
if (subtask.time === parseTimeMS(state.config.time || '1s')) delete subtask.time;
if (subtask.memory === parseMemoryMB(state.config.memory || '256m')) delete subtask.memory;
if (subtask.time) subtask.time += 'ms';
if (subtask.memory) subtask.memory += 'MB';
}
store.dispatch({
type: 'CONFIG_AUTOCASES_UPDATE',
value,
});
});
render(
<Provider store={store}>
<div className="row">
@@ -182,20 +202,7 @@ const page = new NamedPage('problem_config', () => {
<ProblemConfigEditor />
</div>
<div className="medium-7 columns">
<ProblemConfigForm
onAutoLoad={async () => {
const testdata = (reduxStore.getState().testdata || []).map((i) => i.name);
const checkFile = ensureFile(testdata);
let autocases = await readCasesFromFiles(testdata, checkFile, {});
if (!autocases.count) {
autocases = await readSubtasksFromFiles(testdata, checkFile, {}, { subtasks: [] });
}
reduxStore.dispatch({
type: 'CONFIG_AUTOCASES_UPDATE',
value: autocases,
});
}}
/>
<ProblemConfigForm />
</div>
</div>
<button className="rounded primary button" onClick={() => uploadConfig(store.getState().config)}>{i18n('Submit')}</button>