expand sections by default

This commit is contained in:
undefined authored and panda committed 2022-05-10 01:55:57 +08:00
1 parent 539a1c44ce
commit 3b97159879
10 files changed
+54 -120

No files matched your search

@@ -17,6 +17,7 @@ export interface AutoCompleteProps<Item> {
*/ */
height?: string; height?: string;
disabled?: boolean; disabled?: boolean;
placeholder?: string;
disabledHint?: string; disabledHint?: string;
listStyle?: React.CSSProperties; listStyle?: React.CSSProperties;
cacheKey?: string; cacheKey?: string;
@@ -295,6 +296,7 @@ const AutoComplete = forwardRef(function Impl<T>(props: AutoCompleteProps<T>, re
if (allowEmptyQuery) handleInputChange(); if (allowEmptyQuery) handleInputChange();
setFocused(true); setFocused(true);
}} }}
placeholder={props.placeholder}
onBlur={() => setFocused(false)} onBlur={() => setFocused(false)}
onKeyDown={handleInputKeyDown} onKeyDown={handleInputKeyDown}
defaultValue={multi ? '' : selectedKeys.join(',')} defaultValue={multi ? '' : selectedKeys.join(',')}
@@ -344,6 +346,7 @@ AutoComplete.propTypes = {
allowEmptyQuery: PropTypes.bool, allowEmptyQuery: PropTypes.bool,
freeSolo: PropTypes.bool, freeSolo: PropTypes.bool,
freeSoloConverter: PropTypes.func, freeSoloConverter: PropTypes.func,
placeholder: PropTypes.string,
}; };
AutoComplete.defaultProps = { AutoComplete.defaultProps = {
@@ -1,8 +1,8 @@
import React, { useState } from 'react'; import React from 'react';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import i18n from 'vj/utils/i18n'; import i18n from 'vj/utils/i18n';
import { import {
Card, Switch, Tab, Tabs, InputGroup, Tag, Card, Tab, Tabs, InputGroup, Tag,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import type { RootState } from './reducer/index'; import type { RootState } from './reducer/index';
import CustomSelectAutoComplete from '../autocomplete/components/CustomSelectAutoComplete'; import CustomSelectAutoComplete from '../autocomplete/components/CustomSelectAutoComplete';
@@ -35,48 +35,43 @@ function FileIOConfig() {
} }
function ExtraFilesConfig() { function ExtraFilesConfig() {
const [showTab, setshowTab] = useState(false);
const Files = useSelector((state: RootState) => state.testdata); const Files = useSelector((state: RootState) => state.testdata);
const userExtraFiles = useSelector((state: RootState) => state.config.user_extra_files); const userExtraFiles = useSelector((state: RootState) => state.config.user_extra_files);
const judgeExtraFiles = useSelector((state: RootState) => state.config.judge_extra_files); const judgeExtraFiles = useSelector((state: RootState) => state.config.judge_extra_files);
const dispatch = useDispatch(); const dispatch = useDispatch();
return ( return (
<FormItem columns={12} label="ExtraFilesTabs" disableLabel> <FormItem columns={12} label="ExtraFilesTabs" disableLabel>
<Switch checked={showTab} label={i18n('Extra Files Config')} onChange={() => setshowTab(!showTab)} /> <Tabs id="ExtraFilesTabs">
<div style={!showTab ? { display: 'none' } : {}}> <Tab
<Tabs id="ExtraFilesTabs"> id="user_extra_files"
<Tab title={i18n('user_extra_files')}
id="user_extra_files" panel={(
title={i18n('user_extra_files')} <FileSelectAutoComplete
panel={( data={Files}
<FileSelectAutoComplete selectedKeys={userExtraFiles || []}
data={Files} onChange={(val) => dispatch({ type: 'CONFIG_FORM_UPDATE', key: 'user_extra_files', value: val.split(',') })}
selectedKeys={userExtraFiles || []} multi
onChange={(val) => dispatch({ type: 'CONFIG_FORM_UPDATE', key: 'user_extra_files', value: val.split(',') })} />
multi )}
/> />
)} <Tab
/> id="judge_extra_files"
<Tab title={i18n('judge_extra_files')}
id="judge_extra_files" panel={(
title={i18n('judge_extra_files')} <FileSelectAutoComplete
panel={( data={Files}
<FileSelectAutoComplete selectedKeys={judgeExtraFiles || []}
data={Files} onChange={(val) => dispatch({ type: 'CONFIG_FORM_UPDATE', key: 'judge_extra_files', value: val.split(',') })}
selectedKeys={judgeExtraFiles || []} multi
onChange={(val) => dispatch({ type: 'CONFIG_FORM_UPDATE', key: 'judge_extra_files', value: val.split(',') })} />
multi )}
/> />
)} </Tabs>
/>
</Tabs>
</div>
</FormItem> </FormItem>
); );
} }
function LangConfig() { function LangConfig() {
const [showTab, setshowTab] = useState(false);
const langs = useSelector((state: RootState) => state.config.langs) || []; const langs = useSelector((state: RootState) => state.config.langs) || [];
const prefixes = new Set(Object.keys(LANGS).filter((i) => i.includes('.')).map((i) => i.split('.')[0])); const prefixes = new Set(Object.keys(LANGS).filter((i) => i.includes('.')).map((i) => i.split('.')[0]));
const data = Object.keys(LANGS).filter((i) => !prefixes.has(i)) const data = Object.keys(LANGS).filter((i) => !prefixes.has(i))
@@ -88,21 +83,19 @@ function LangConfig() {
ref.current.setSelectedKeys(selectedKeys); ref.current.setSelectedKeys(selectedKeys);
}, [JSON.stringify(selectedKeys)]); }, [JSON.stringify(selectedKeys)]);
return ( return (
<FormItem columns={12} label="LangsTabs" disableLabel> <FormItem columns={12} label="langs">
<Switch checked={showTab} label={i18n('Langs Config')} onChange={() => setshowTab(!showTab)} /> <CustomSelectAutoComplete
<FormItem columns={12} label="langs" style={!showTab ? { display: 'none' } : {}}> ref={ref}
<CustomSelectAutoComplete data={data}
ref={ref} placeholder={i18n('Unlimited')}
data={data} selectedKeys={selectedKeys}
selectedKeys={selectedKeys} onChange={(val) => {
onChange={(val) => { const value = val.split(',');
const value = val.split(','); value.push(...Array.from(new Set(value.filter((i) => i.includes('.')).map((i) => i.split('.')[0]))));
value.push(...Array.from(new Set(value.filter((i) => i.includes('.')).map((i) => i.split('.')[0])))); dispatch({ type: 'CONFIG_FORM_UPDATE', key: 'langs', value });
dispatch({ type: 'CONFIG_FORM_UPDATE', key: 'langs', value }); }}
}} multi
multi />
/>
</FormItem>
</FormItem> </FormItem>
); );
} }
+2
View File
@@ -141,6 +141,7 @@ Compile Error: 编译错误
Compilers' Version and Parameters: 编译器版本及参数 Compilers' Version and Parameters: 编译器版本及参数
Complete: 完成 Complete: 完成
Completed: 已完成 Completed: 已完成
Config: 配置
Confirm deleting the selected roles?: 您确定删除所选角色吗? Confirm deleting the selected roles?: 您确定删除所选角色吗?
Confirm deleting this comment? Its replies will be deleted as well.: 确认删除这个评论吗?回复会被同时删除。 Confirm deleting this comment? Its replies will be deleted as well.: 确认删除这个评论吗?回复会被同时删除。
Confirm deleting this reply?: 确认删除这个回复吗? Confirm deleting this reply?: 确认删除这个回复吗?
@@ -825,6 +826,7 @@ Uncompleted: 未完成
Unique: 唯一 Unique: 唯一
Unknown field {0}.: 未知字段 {0}。 Unknown field {0}.: 未知字段 {0}。
Unknown: 未知 Unknown: 未知
Unlimited: 无限制
Unordered List: 无序列表 Unordered List: 无序列表
Unstar Topic: 取消收藏 Unstar Topic: 取消收藏
Unstar: 取消收藏 Unstar: 取消收藏
@@ -4,13 +4,6 @@
max-height: 270px max-height: 270px
overflow-y: auto overflow-y: auto
&.collapsed .collapsed--hidden,
&.expanded .expanded--hidden
display: none
&.collapsed .problem-sidebar-testdata__detail
display: none
.col--size .col--size
width: 80px width: 80px
.col--operation .col--operation
@@ -1,5 +1,4 @@
import { NamedPage } from 'vj/misc/Page'; import { NamedPage } from 'vj/misc/Page';
import { slideDown, slideUp } from 'vj/utils/slide';
import request from 'vj/utils/request'; import request from 'vj/utils/request';
import loadReactRedux from 'vj/utils/loadReactRedux'; import loadReactRedux from 'vj/utils/loadReactRedux';
import i18n from 'vj/utils/i18n'; import i18n from 'vj/utils/i18n';
@@ -12,21 +11,6 @@ import tpl from 'vj/utils/tpl';
import { SubtaskType } from 'hydrooj/src/interface'; import { SubtaskType } from 'hydrooj/src/interface';
import { configYamlFormat } from 'vj/components/problemconfig/ProblemConfigEditor'; import { configYamlFormat } from 'vj/components/problemconfig/ProblemConfigEditor';
async function handleSection(ev: JQuery.ClickEvent<Document, undefined, any, any>, type: string) {
const $section = $(ev.currentTarget).closest('.section--problem-sidebar-testdata');
if ($section.is(`.${type}d, .animating`)) return;
$section.addClass('animating');
const $detail = $section.find('.problem-sidebar-testdata__detail');
if (type === 'expand') {
await slideDown($detail, 300, { opacity: 0 }, { opacity: 1 });
} else {
await slideUp($detail, 300, { opacity: 1 }, { opacity: 0 });
}
$section.addClass(type === 'expand' ? 'expanded' : 'collapsed');
$section.removeClass(type === 'expand' ? 'collapsed' : 'expanded');
$section.removeClass('animating');
}
function onBeforeUnload(e) { function onBeforeUnload(e) {
e.returnValue = ''; e.returnValue = '';
} }
@@ -216,8 +200,6 @@ const page = new NamedPage('problem_config', () => {
$(document).on('click', '[name="testdata__upload"]', () => handleClickUpload()); $(document).on('click', '[name="testdata__upload"]', () => handleClickUpload());
$(document).on('click', '[name="testdata__delete"]', (ev) => handleClickRemove(ev)); $(document).on('click', '[name="testdata__delete"]', (ev) => handleClickRemove(ev));
$(document).on('click', '[name="testdata__download__all"]', () => handleClickDownloadAll()); $(document).on('click', '[name="testdata__download__all"]', () => handleClickDownloadAll());
$(document).on('click', '[name="testdata__section__expand"]', (ev) => handleSection(ev, 'expand'));
$(document).on('click', '[name="testdata__section__collapse"]', (ev) => handleSection(ev, 'collapse'));
}); });
export default page; export default page;
@@ -12,26 +12,11 @@
&.tab--active &.tab--active
border-color: #ed5f82; border-color: #ed5f82;
.section--problem-sidebar-tags
&.collapsed .collapsed--hidden,
&.expanded .expanded--hidden
display: none
&.collapsed .problem-sidebar-tags__detail
display: none
.section--problem-sidebar-additional_file .section--problem-sidebar-additional_file
.problem-sidebar-additional_file__detail .problem-sidebar-additional_file__detail
height: 270px height: 270px
overflow-y: auto overflow-y: auto
&.collapsed .collapsed--hidden,
&.expanded .expanded--hidden
display: none
&.collapsed .problem-sidebar-additional_file__detail
display: none
.col--size .col--size
width: 80px width: 80px
.col--operation .col--operation
@@ -1,8 +1,8 @@
{% import "components/nothing.html" as nothing with context %} {% import "components/nothing.html" as nothing with context %}
{% import "components/problem.html" as problem with context %} {% import "components/problem.html" as problem with context %}
<div class="section side section--problem-sidebar-additional_file {{ 'expanded' if page_name == 'problem_edit' else 'collapsed'}}"> <div class="section side section--problem-sidebar-additional_file">
<div class="section__header"> <div class="section__header">
<h1 class="section__title">{{ additional_file.length if additional_file.length else 0 }} {{_('Additional File')}}</h1> <h1 class="section__title">{{ additional_file.length|default(0) }} {{_('Additional File')}}</h1>
</div> </div>
<ol class="menu"> <ol class="menu">
<li class="menu__item flex-row"> <li class="menu__item flex-row">
@@ -13,15 +13,6 @@
<span class="icon icon-download"></span> {{ _('Download All') }} <span class="icon icon-download"></span> {{ _('Download All') }}
</a> </a>
</li> </li>
<li class="menu__seperator"></li>
<li class="menu__item">
<a class="menu__link expanded--hidden" href="javascript:;" name="additional_file__section__expand">
<span class="icon icon-expand_more"></span> {{ _('expand') }}
</a>
<a class="menu__link collapsed--hidden" href="javascript:;" name="additional_file__section__collapse">
<span class="icon icon-expand_less"></span> {{ _('collapse') }}
</a>
</li>
</ol> </ol>
<div class="section__body no-padding problem-sidebar-additional_file__detail" data-fragment-id="problem-sidebar-additional_file"> <div class="section__body no-padding problem-sidebar-additional_file__detail" data-fragment-id="problem-sidebar-additional_file">
{% if additional_file.length %} {% if additional_file.length %}
@@ -1,6 +1,6 @@
{% import "components/nothing.html" as nothing with context %} {% import "components/nothing.html" as nothing with context %}
{% import "components/problem.html" as problem with context %} {% import "components/problem.html" as problem with context %}
<div class="section side section--problem-sidebar-testdata collapsed"> <div class="section side section--problem-sidebar-testdata">
<div class="section__header"> <div class="section__header">
<h1 class="section__title">{{ testdata.length if testdata.length else 0 }} {{_('Testdata')}}</h1> <h1 class="section__title">{{ testdata.length if testdata.length else 0 }} {{_('Testdata')}}</h1>
</div> </div>
@@ -14,14 +14,6 @@
</a> </a>
</li> </li>
<li class="menu__seperator"></li> <li class="menu__seperator"></li>
<li class="menu__item flex-row">
<a class="menu__link expanded--hidden" href="javascript:;" name="testdata__section__expand">
<span class="icon icon-expand_more"></span> {{ _('expand') }}
</a>
<a class="menu__link collapsed--hidden" href="javascript:;" name="testdata__section__collapse">
<span class="icon icon-expand_less"></span> {{ _('collapse') }}
</a>
</li>
</ol> </ol>
<div class="section__body no-padding problem-sidebar-testdata__detail" data-fragment-id="problem-sidebar-testdata"> <div class="section__body no-padding problem-sidebar-testdata__detail" data-fragment-id="problem-sidebar-testdata">
{% if testdata.length %} {% if testdata.length %}
@@ -49,7 +41,7 @@
</tbody> </tbody>
</table> </table>
{% else %} {% else %}
{{ nothing.render('No testdata at current.',compact = true) }} {{ nothing.render('No testdata at current.', compact = true) }}
{% endif %} {% endif %}
</div> </div>
</div> </div>
@@ -92,17 +92,9 @@
</div> </div>
</div> </div>
<div class="medium-3 columns"> <div class="medium-3 columns">
<div class="section side visiable nojs--hide section--problem-sidebar-tags {{ 'collapsed' if page_name == 'problem_edit' else 'expanded'}}"> <div class="section side visiable nojs--hide section--problem-sidebar-tags">
<div class="section__header"> <div class="section__header">
<h1 class="section__title">{{ _('Categories') }} ({{ _('click to add') }})</h1> <h1 class="section__title">{{ _('Categories') }} ({{ _('click to add') }})</h1>
<div class="section__tools">
<a class="expanded--hidden" href="javascript:;" name="tags__section__expand">
<span class="icon icon-expand_more"></span>
</a>
<a class="collapsed--hidden" href="javascript:;" name="tags__section__collapse">
<span class="icon icon-expand_less"></span>
</a>
</div>
</div> </div>
<div class="section__body problem-sidebar-tags__detail"> <div class="section__body problem-sidebar-tags__detail">
{% include "partials/category.html" %} {% include "partials/category.html" %}
@@ -7,8 +7,9 @@
<h1 class="section__title">{{ _('Testdata') }}</h1> <h1 class="section__title">{{ _('Testdata') }}</h1>
<div class="section__tools"> <div class="section__tools">
{% if not reference and (handler.user.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.user.hasPerm(perm.PERM_EDIT_PROBLEM)) %} {% if not reference and (handler.user.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.user.hasPerm(perm.PERM_EDIT_PROBLEM)) %}
<button class="primary rounded button" name="create_testdata">{{ _('Create File') }}</button> <a href="{{ url('problem_config', pid=pdoc.docId) }}" class="primary rounded button">{{ _('Config') }}</a>
<button class="primary rounded button" name="upload_testdata">{{ _('Upload File') }}</button> <button class="primary rounded button" name="create_testdata">{{ _('Create') }}</button>
<button class="primary rounded button" name="upload_testdata">{{ _('Upload') }}</button>
{% endif %} {% endif %}
</div> </div>
</div> </div>