core&ui: add language filter (#346)

This commit is contained in:
panda authored and GitHub committed 2022-04-25 22:26:08 +08:00
1 parent 59f1b4e429
commit 84d69bc348
7 files changed
+57 -34

No files matched your search

+5 -1
View File
@@ -25,12 +25,14 @@ class RecordListHandler extends Handler {
@param('pid', Types.Name, true)
@param('tid', Types.ObjectID, true)
@param('uidOrName', Types.Name, true)
@param('lang', Types.String, true)
@param('status', Types.Int, true)
@param('fullStatus', Types.Boolean)
@param('allDomain', Types.Boolean, true)
async get(
domainId: string, page = 1, pid?: string, tid?: ObjectID,
uidOrName?: string, status?: number, full = false, all = false,
uidOrName?: string, lang?: string, status?: number, full = false,
all = false,
) {
let tdoc = null;
let invalid = false;
@@ -60,6 +62,7 @@ class RecordListHandler extends Handler {
if (pdoc) q.pid = pdoc.docId;
else invalid = true;
}
if (lang) q.lang = lang;
if (status) q.status = status;
if (all) {
this.checkPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN);
@@ -90,6 +93,7 @@ class RecordListHandler extends Handler {
filterPid: pid,
filterTid: tid,
filterUidOrName: uidOrName,
filterLang: lang,
filterStatus: status,
};
if (this.user.hasPriv(PRIV.PRIV_VIEW_JUDGE_STATISTICS) && !full) {
@@ -7,6 +7,7 @@ import { connect } from 'react-redux';
import i18n from 'vj/utils/i18n';
import request from 'vj/utils/request';
import Icon from 'vj/components/react/IconComponent';
import getAvaliableLangs from 'vj/utils/avaliableLangs';
import Toolbar, {
ToolbarItemComponent as ToolbarItem,
ToolbarButtonComponent as ToolbarButton,
@@ -66,15 +67,8 @@ const mapDispatchToProps = (dispatch) => ({
},
});
const LANGS = {};
const prefix = new Set(Object.keys(window.LANGS).filter((i) => i.includes('.')).map((i) => i.split('.')[0]));
for (const key in window.LANGS) {
if (prefix.has(key)) continue;
if (UiContext.pdoc.config.langs && !UiContext.pdoc.config.langs.includes(key)) continue;
if (window.LANGS[key].hidden && !UiContext.pdoc.config.langs?.includes(key)) continue;
LANGS[key] = window.LANGS[key];
}
const keys = Object.keys(LANGS);
const avaliableLangs = getAvaliableLangs(UiContext.pdoc.config.langs);
const keys = Object.keys(avaliableLangs);
export default connect(mapStateToProps, mapDispatchToProps)(class ScratchpadToolbarContainer extends React.PureComponent {
static contextTypes = {
@@ -83,10 +77,10 @@ export default connect(mapStateToProps, mapDispatchToProps)(class ScratchpadTool
constructor(props) {
super(props);
if (!LANGS[this.props.editorLang]) {
if (!avaliableLangs[this.props.editorLang]) {
// preference not allowed
const key = keys.find((i) => LANGS[i].pretest === this.props.editorLang);
this.props.setEditorLanguage(key || Object.keys(LANGS)[0]);
const key = keys.find((i) => avaliableLangs[i].pretest === this.props.editorLang);
this.props.setEditorLanguage(key || keys[0]);
}
}
@@ -97,9 +91,9 @@ export default connect(mapStateToProps, mapDispatchToProps)(class ScratchpadTool
render() {
let canUsePretest = ['default', 'fileio'].includes(UiContext.pdoc.config?.type);
if (UiContext.pdoc.config?.type === 'remote_judge') {
if (window.LANGS[this.props.editorLang].pretest) canUsePretest = true;
if (avaliableLangs[this.props.editorLang].pretest) canUsePretest = true;
}
if (window.LANGS[this.props.editorLang].pretest === false) canUsePretest = false;
if (avaliableLangs[this.props.editorLang].pretest === false) canUsePretest = false;
return (
<Toolbar>
{canUsePretest && (
+2
View File
@@ -68,6 +68,7 @@ Add: 添加
All {0} Contests: 所有 {0} 比赛
All Contests: 所有比赛
All Homeworks: 所有作业
All Languages: 所有语言
All Submissions: 所有递交
All Training Plans: 所有训练计划
All: 全部
@@ -100,6 +101,7 @@ Built-in: 内置
Bulletin: 公告
By clicking the button, you will become a member of the domain {0}.: 点击按钮,您将成为域 {0} 的成员。
By Contest: 由比赛
By Language: 由语言
By Problem: 由题目
By signing up a {0} universal account, you can submit code and join discussions in all online judging services provided by us.: 注册一个 {0} 通用账户,您就可以在我们提供的所有在线评测服务上提交代码、参与讨论。
By Status: 由状态
@@ -1,4 +1,5 @@
import { NamedPage } from 'vj/misc/Page';
import getAvaliableLangs from 'vj/utils/avaliableLangs';
function setOptions($el, options) {
$el.empty();
@@ -9,13 +10,12 @@ function setOptions($el, options) {
const page = new NamedPage(['problem_submit', 'contest_detail_problem_submit', 'homework_detail_problem_submit'], async () => {
const { config } = UiContext.pdoc;
const avaliableLangs = getAvaliableLangs(config.langs);
function onChangeMain(update = true) {
const options = {};
for (const key in window.LANGS) {
if (config.langs && !config.langs.includes(key)) continue;
if (window.LANGS[key].hidden && !config.langs?.includes(key)) continue;
if (key.startsWith(`${this.value}.`) && key !== this.value) options[key] = window.LANGS[key].display;
for (const key in avaliableLangs) {
if (key.startsWith(`${this.value}.`) && key !== this.value) options[key] = avaliableLangs[key].display;
}
setOptions($('#codelang-sub-select'), options);
if (Object.keys(options).length) {
@@ -28,9 +28,8 @@ const page = new NamedPage(['problem_submit', 'contest_detail_problem_submit', '
return Object.keys(options)[0];
}
const main = {};
for (const key in window.LANGS) {
for (const key in avaliableLangs) {
if (config.langs && !config.langs.filter((i) => i === key || i.startsWith(`${key}.`)).length) continue;
if (window.LANGS[key].hidden && !config.langs?.includes(key)) continue;
if (!key.includes('.')) main[key] = window.LANGS[key].display;
else {
const a = key.split('.')[0];
@@ -1,6 +1,8 @@
import { NamedPage } from 'vj/misc/Page';
import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete';
import ProblemSelectAutoComplete from 'vj/components/autocomplete/ProblemSelectAutoComplete';
import tpl from 'vj/utils/tpl';
import getAvaliableLangs from 'vj/utils/avaliableLangs';
const page = new NamedPage('record_main', async () => {
const [{ default: SockJs }, { DiffDOM }] = await Promise.all([
@@ -36,6 +38,11 @@ const page = new NamedPage('record_main', async () => {
ProblemSelectAutoComplete.getOrConstruct($('[name="pid"]'), {
clearDefaultValue: false,
});
const avaliableLangs = getAvaliableLangs(UiContext.domain.langs?.split(','));
Object.keys(avaliableLangs).map(
(i) => ($('select[name="lang"]').append(tpl`<option value="${i}" key="${i}">${avaliableLangs[i].display}</option>`)));
const lang = new URL(window.location.href).searchParams.get('lang');
if (lang) $('select[name="lang"]').val(lang);
});
export default page;
+18 -13
View File
@@ -22,37 +22,41 @@
</div>
<div class="section__body">
<div class="row">
<div class="medium-3 columns">
<div class="medium-2 columns">
<label class="filter-user">
{{ _('By Username / UID') }}
<input name="uidOrName" type="text" class="textbox" value="{{ filterUidOrName }}" autocomplete="off" data-autofocus>
</label>
</div>
<div class="medium-3 columns">
<div class="medium-2 columns">
<label>
{{ _('By Problem') }}
<input name="pid" type="text" class="textbox" value="{{ filterPid }}">
</label>
</div>
<div class="medium-3 columns">
<div class="medium-2 columns">
<label>
{{ _('By Contest') }}
<input name="tid" type="text" class="textbox" value="{{ filterTid }}">
</label>
</div>
<div class="medium-3 columns nojs-hide">
<label>
{{ _('By Language') }}
</label>
<select class="compact select" name="lang">
<option value="">{{ _('All Languages') }}</option>
</select>
</div>
<div class="medium-3 columns">
<label>
{{ _('By Status') }}
</label>
<select class="compact select" name="status">
<option value="">{{ _('All Submissions') }}</option>
<option value="1">Accepted</option>
<option value="2">Wrong Answer</option>
<option value="3">Time Limit Exceeded</option>
<option value="4">Memory Limit Exceeded</option>
<option value="6">Runtime Error</option>
<option value="7">Compile Error</option>
<option value="8">System Error</option>
<option value="" {% if not filterStatus %}selected{% else %}{% endif %}>{{ _('All Submissions') }}</option>
{%- for k,v in utils.status.STATUS_TEXTS -%}
<option value="{{k}}" {% if filterStatus == k %}selected{% else %}{% endif %}>{{v}}</option>
{%- endfor -%}
</select>
</div>
</div>
@@ -61,12 +65,12 @@
</form>
<div class="section">
<div class="section__body no-padding">
{% if not rdocs %}
{% if not rdocs.length %}
{% if not filterUidOrName and not filterPid and not filterTid %}
{{ nothing.render('Oh, there is no task in the queue!') }}
{% else %}
{{ nothing.render('Oh, there is no task that matches the filter!') }}
{% endif%}
{% endif %}
{% else %}
<table class="data-table record_main__table">
<colgroup>
@@ -103,6 +107,7 @@
<a class="pager__item next link" href="?page={{ page + 1 }}{{
(('&tid=' + filterTid) if filterTid else '')
+ (('&uidOrName=' + filterUidOrName) if filterUidOrName else '')
+ (('&language=' + filterLanguage) if filterLanguage else '')
+ (('&status=' + filterStatus) if filterStatus else '')
+ (('&pid=' + filterPid) if filterPid else '')
+ ('&allDomain=1' if all else '') }}">{{ _('pager_next') }}</a>
@@ -0,0 +1,12 @@
const prefixes = new Set(Object.keys(LANGS).filter((i) => i.includes('.')).map((i) => i.split('.')[0]));
export default function getAvaliableLangs(langsList?: string[]) {
const Langs = {};
for (const key in LANGS) {
if (prefixes.has(key)) continue;
if (langsList && !langsList.includes(key)) continue;
if (LANGS[key].hidden && !langsList?.includes(key)) continue;
Langs[key] = LANGS[key];
}
return Langs;
}