From f33e2b932ad453877ef6e161b3a0ec6cad31fb3e Mon Sep 17 00:00:00 2001 From: undefined Date: Mon, 25 Oct 2021 18:35:03 +0800 Subject: [PATCH] core: bulk copy --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/problem.ts | 17 +++++++++- packages/ui-default/locales/zh.yaml | 1 + packages/ui-default/package.json | 2 +- .../ui-default/pages/problem_main.page.js | 33 ++++++++++++++----- .../ui-default/templates/problem_main.html | 12 ++++--- 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index b542e6f3b..ec1b02cec 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "3.1.3", + "version": "3.1.4", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 7c56a83c5..7a8c0136b 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -155,6 +155,21 @@ export class ProblemMainHandler extends ProblemHandler { this.back({ star: false }); } + @param('pids', Types.NumericArray) + @param('target', Types.String) + async postCopy(domainId: string, pids: number[], target: string) { + const ddoc = await domain.get(target); + if (!ddoc) throw new NotFoundError(target); + const dudoc = await user.getById(target, this.user._id); + if (!dudoc.hasPerm(PERM.PERM_CREATE_PROBLEM)) throw new PermissionError(PERM.PERM_CREATE_PROBLEM); + const ids = []; + for (const pid of pids) { + // eslint-disable-next-line no-await-in-loop + ids.push(await problem.copy(domainId, pid, target)); + } + this.response.body = ids; + } + @param('pids', Types.NumericArray) async postDelete(domainId: string, pids: number[]) { for (const pid of pids) { @@ -297,7 +312,7 @@ export class ProblemDetailHandler extends ProblemHandler { if (!ddoc) throw new NotFoundError(target); const dudoc = await user.getById(target, this.user._id); if (!dudoc.hasPerm(PERM.PERM_CREATE_PROBLEM)) throw new PermissionError(PERM.PERM_CREATE_PROBLEM); - const docId = await problem.copy(domainId, this.user.docId, target, this.pdoc.pid); + const docId = await problem.copy(domainId, this.pdoc.docId, target); this.response.redirect = this.url('problem_detail', { domainId: target, pid: docId }); } diff --git a/packages/ui-default/locales/zh.yaml b/packages/ui-default/locales/zh.yaml index 75af87259..3966095e8 100644 --- a/packages/ui-default/locales/zh.yaml +++ b/packages/ui-default/locales/zh.yaml @@ -158,6 +158,7 @@ Contributions: 贡献 Copy Email: 复制电子邮件 Copy from: 复制自 Copy QQ Number: 复制QQ号 +Copy Selected: 复制选中 Copy WeChat Account: 复制微信号 Copy: 复制 Copyright Complaint: 版权申诉 diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index b2231e66f..bed46a9db 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.26.2", + "version": "4.26.3", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/pages/problem_main.page.js b/packages/ui-default/pages/problem_main.page.js index c1c1053c9..4464b0771 100644 --- a/packages/ui-default/pages/problem_main.page.js +++ b/packages/ui-default/pages/problem_main.page.js @@ -2,7 +2,7 @@ import _ from 'lodash'; import $ from 'jquery'; import { NamedPage } from 'vj/misc/Page'; import Notification from 'vj/components/notification'; -import { ConfirmDialog } from 'vj/components/dialog'; +import { ActionDialog, ConfirmDialog } from 'vj/components/dialog'; import Dropdown from 'vj/components/dropdown/Dropdown'; import createHint from 'vj/components/hint'; import { downloadProblemSet } from 'vj/components/zipDownloader'; @@ -174,17 +174,32 @@ function ensureAndGetSelectedPids() { async function handleOperation(operation) { const pids = ensureAndGetSelectedPids(); if (pids === null) return; + const payload = {}; if (operation === 'delete') { const action = await new ConfirmDialog({ - $body: tpl` -
-

${i18n('Confirm to delete the selected problems?')}

-
`, + $body: tpl.typoMsg(i18n('Confirm to delete the selected problems?')), }).open(); if (action !== 'yes') return; + } else if (operation === 'copy') { + const action = await new ActionDialog({ + $body: tpl` +
+ +
+ `, + }).open(); + if (action !== 'ok') return; + const target = $('[name="target"]').val(); + if (!target) return; + payload.target = target; } try { - await request.post('', { operation, pids }); + await request.post('', { operation, pids, ...payload }); Notification.success(i18n(`Selected problems have been ${operation}d.`)); await delay(2000); window.location.reload(); @@ -213,9 +228,9 @@ const page = new NamedPage(['problem_main', 'problem_category'], () => { $('[name="enter-edit-mode"]').on('click', () => { doc.className = doc.className.replace(' display-mode', ' edit-mode'); }); - $('[name="remove_selected_problems"]').on('click', () => handleOperation('delete')); - $('[name="hide_selected_problems"]').on('click', () => handleOperation('hide')); - $('[name="unhide_selected_problems"]').on('click', () => handleOperation('unhide')); + ['delete', 'hide', 'unhide', 'copy'].forEach((op) => { + $(`[name="${op}_selected_problems"]`).on('click', () => handleOperation(op)); + }); $('[name="download_selected_problems"]').on('click', handleDownload); $('#hideTags').on('click', () => $('.problem__tags').hide()); $('#search').on('click', (ev) => { diff --git a/packages/ui-default/templates/problem_main.html b/packages/ui-default/templates/problem_main.html index 9af12c8ae..643df12cd 100644 --- a/packages/ui-default/templates/problem_main.html +++ b/packages/ui-default/templates/problem_main.html @@ -24,8 +24,8 @@ -
- {% if handler.user.hasPerm(perm.PERM_EDIT_PROBLEM) %} + {% if handler.user.hasPriv(PRIV.PRIV_USER_PROFILE) %} +