mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
ui: add ProblemSelectAutoComplete
This commit is contained in:
1 parent
1c89596cb3
commit
90443546c8
7 files changed
+80
-3
No files matched your search
@@ -581,6 +581,15 @@ export class ProblemCreateHandler extends Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ProblemPrefixListHandler extends Handler {
|
||||||
|
@param('prefix', Types.Name)
|
||||||
|
async get(domainId: string, prefix: string) {
|
||||||
|
this.response.body = {
|
||||||
|
pdocs: await problem.getPrefixList(domainId, prefix),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function apply() {
|
export async function apply() {
|
||||||
Route('problem_main', '/p', ProblemMainHandler, PERM.PERM_VIEW_PROBLEM);
|
Route('problem_main', '/p', ProblemMainHandler, PERM.PERM_VIEW_PROBLEM);
|
||||||
Route('problem_category', '/p/category/:category', ProblemCategoryHandler, PERM.PERM_VIEW_PROBLEM);
|
Route('problem_category', '/p/category/:category', ProblemCategoryHandler, PERM.PERM_VIEW_PROBLEM);
|
||||||
@@ -596,6 +605,7 @@ export async function apply() {
|
|||||||
Route('problem_solution_raw', '/p/:pid/solution/:psid/raw', ProblemSolutionRawHandler, PERM.PERM_VIEW_PROBLEM);
|
Route('problem_solution_raw', '/p/:pid/solution/:psid/raw', ProblemSolutionRawHandler, PERM.PERM_VIEW_PROBLEM);
|
||||||
Route('problem_solution_reply_raw', '/p/:pid/solution/:psid/:psrid/raw', ProblemSolutionRawHandler, PERM.PERM_VIEW_PROBLEM);
|
Route('problem_solution_reply_raw', '/p/:pid/solution/:psid/:psrid/raw', ProblemSolutionRawHandler, PERM.PERM_VIEW_PROBLEM);
|
||||||
Route('problem_create', '/problem/create', ProblemCreateHandler, PERM.PERM_CREATE_PROBLEM);
|
Route('problem_create', '/problem/create', ProblemCreateHandler, PERM.PERM_CREATE_PROBLEM);
|
||||||
|
Route('problem_prefix_list', '/problem/list', ProblemPrefixListHandler, PERM.PERM_VIEW_PROBLEM);
|
||||||
Connection('problem_pretest_conn', '/conn/pretest', ProblemPretestConnectionHandler, PERM.PERM_SUBMIT_PROBLEM);
|
Connection('problem_pretest_conn', '/conn/pretest', ProblemPretestConnectionHandler, PERM.PERM_SUBMIT_PROBLEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { Readable } from 'stream';
|
import type { Readable } from 'stream';
|
||||||
import { ObjectID, FilterQuery } from 'mongodb';
|
import { ObjectID, FilterQuery } from 'mongodb';
|
||||||
import { Dictionary, pick } from 'lodash';
|
import { Dictionary, escapeRegExp, pick } from 'lodash';
|
||||||
import { STATUS } from './builtin';
|
import { STATUS } from './builtin';
|
||||||
import * as document from './document';
|
import * as document from './document';
|
||||||
import domain from './domain';
|
import domain from './domain';
|
||||||
@@ -208,6 +208,13 @@ export class ProblemModel {
|
|||||||
return Object.assign(r, l);
|
return Object.assign(r, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async getPrefixList(domainId: string, prefix: string) {
|
||||||
|
prefix = prefix.toLowerCase();
|
||||||
|
const $regex = new RegExp(`\\A${escapeRegExp(prefix)}`, 'gmi');
|
||||||
|
const filter = { $or: [{ pid: { $regex } }, { title: { $regex } }] };
|
||||||
|
return await document.getMulti(domainId, document.TYPE_PROBLEM, filter, ['domainId', 'docId', 'pid', 'title']).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
static async getListStatus(domainId: string, uid: number, pids: number[]) {
|
static async getListStatus(domainId: string, uid: number, pids: number[]) {
|
||||||
const psdocs = await ProblemModel.getMultiStatus(
|
const psdocs = await ProblemModel.getMultiStatus(
|
||||||
domainId, { uid, docId: { $in: Array.from(new Set(pids)) } },
|
domainId, { uid, docId: { $in: Array.from(new Set(pids)) } },
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Collection } from 'mongodb';
|
import { Collection } from 'mongodb';
|
||||||
|
import { escapeRegExp } from 'lodash';
|
||||||
import * as system from './system';
|
import * as system from './system';
|
||||||
import token from './token';
|
import token from './token';
|
||||||
import * as setting from './setting';
|
import * as setting from './setting';
|
||||||
@@ -224,7 +225,7 @@ class UserModel {
|
|||||||
@ArgMethod
|
@ArgMethod
|
||||||
static async getPrefixList(domainId: string, prefix: string, limit: number = 50) {
|
static async getPrefixList(domainId: string, prefix: string, limit: number = 50) {
|
||||||
prefix = prefix.toLowerCase();
|
prefix = prefix.toLowerCase();
|
||||||
const $regex = new RegExp(`\\A\\Q${prefix}\\E`, 'gmi');
|
const $regex = new RegExp(`\\A${escapeRegExp(prefix)}`, 'gmi');
|
||||||
const uids = await coll.find({ unameLower: { $regex } })
|
const uids = await coll.find({ unameLower: { $regex } })
|
||||||
.limit(limit).map((doc) => doc._id).toArray();
|
.limit(limit).map((doc) => doc._id).toArray();
|
||||||
const users = [];
|
const users = [];
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export async function connect() {
|
|||||||
while (dbVer < expected) {
|
while (dbVer < expected) {
|
||||||
const func = scripts[dbVer];
|
const func = scripts[dbVer];
|
||||||
dbVer++;
|
dbVer++;
|
||||||
if (func.toString().includes('_FRESH_INSTALL_IGNORE')) continue;
|
if (typeof func !== 'function' || func.toString().includes('_FRESH_INSTALL_IGNORE')) continue;
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await func();
|
await func();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
import tpl from 'vj/utils/tpl';
|
||||||
|
import request from 'vj/utils/request';
|
||||||
|
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||||
|
import AutoComplete from '.';
|
||||||
|
|
||||||
|
function getText(pdoc) {
|
||||||
|
return pdoc.docId;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getItems(val) {
|
||||||
|
return request.get('/problem/list', { q: val });
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderItem(pdoc) {
|
||||||
|
return tpl`
|
||||||
|
<div class="media">
|
||||||
|
<div class="media__body medium">
|
||||||
|
<div class="problem-select__name">${pdoc.pid ? `${pdoc.pid}` : ''}${pdoc.title}</div>
|
||||||
|
<div class="problem-select__id">ID = ${pdoc.docId}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ProblemSelectAutoComplete extends AutoComplete {
|
||||||
|
static DOMAttachKey = 'vjProblemSelectAutoCompleteInstance';
|
||||||
|
|
||||||
|
constructor($dom, options) {
|
||||||
|
super($dom, {
|
||||||
|
classes: 'problem-select',
|
||||||
|
items: getItems,
|
||||||
|
render: renderItem,
|
||||||
|
text: getText,
|
||||||
|
...options,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_.assign(ProblemSelectAutoComplete, DOMAttachedObject);
|
||||||
|
window.Hydro.components.UserSelectAutoComplete = ProblemSelectAutoComplete;
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
|
import UserSelectAutoComplete from './UserSelectAutoComplete';
|
||||||
|
import DomainSelectAutoComplete from './DomainSelectAutoComplete';
|
||||||
|
import ProblemSelectAutoComplete from './ProblemSelectAutoComplete';
|
||||||
|
|
||||||
|
const page = new AutoloadPage('autocomplete', () => {
|
||||||
|
UserSelectAutoComplete.getOrConstruct($('[autocomplete="user"]'));
|
||||||
|
DomainSelectAutoComplete.getOrConstruct($('[autocomplete="domain"]'));
|
||||||
|
ProblemSelectAutoComplete.getOrConstruct($('[autocomplete="problem"]'));
|
||||||
|
});
|
||||||
|
|
||||||
|
export default page;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
.menu.problem-select
|
||||||
|
width: rem(200px)
|
||||||
|
|
||||||
|
.problem-select__uid
|
||||||
|
font-size: rem($font-size-small)
|
||||||
|
color: $userselect-uid-color
|
||||||
Reference in new issue
Block a user