core&ui: add contest private files (#1053)

Co-authored-by: panda <panda_dtdyy@outlook.com>
This commit is contained in:
undefinedandpanda authored and GitHub committed 2025-10-17 10:24:38 +01:00
1 parent 9729346ad9
commit f5ef8b7f38
35 files changed
+781 -843

No files matched your search

+4 -96
View File
@@ -1,15 +1,11 @@
import $ from 'jquery';
import _ from 'lodash';
import { ConfirmDialog } from 'vj/components/dialog';
import { confirm } from 'vj/components/dialog';
import Dropdown from 'vj/components/dropdown/Dropdown';
import Editor from 'vj/components/editor/index';
import Notification from 'vj/components/notification';
import uploadFiles from 'vj/components/upload';
import download from 'vj/components/zipDownloader';
import { NamedPage } from 'vj/misc/Page';
import {
i18n, pjax, request, slideDown, slideUp, tpl,
} from 'vj/utils';
import { i18n, request } from 'vj/utils';
const categories = {};
const dirtyCategories = [];
@@ -139,21 +135,6 @@ function buildCategoryFilter() {
});
}
async function handleSection(ev, sidebar, type) {
const $section = $(ev.currentTarget).closest(`.section--problem-sidebar-${sidebar}`);
if ($section.is(`.${type}d, .animating`)) return;
$section.addClass('animating');
const $detail = $section.find(`.section--problem-sidebar-${sidebar}__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');
}
export default new NamedPage(['problem_create', 'problem_edit'], () => {
let confirmed = false;
$(document).on('click', '[name="operation"]', (ev) => {
@@ -165,14 +146,8 @@ export default new NamedPage(['problem_create', 'problem_edit'], () => {
Notification.error(e.message);
});
}
const message = 'Confirm deleting this problem? Its files, submissions, discussions and solutions will be deleted as well.';
return new ConfirmDialog({
$body: tpl`
<div class="typo">
<p>${i18n(message)}</p>
</div>`,
}).open().then((action) => {
if (action !== 'yes') return;
return confirm(i18n('Confirm deleting this problem? Its files, submissions, discussions and solutions will be deleted as well.')).then((yes) => {
if (!yes) return;
confirmed = true;
ev.target.click();
});
@@ -181,65 +156,6 @@ export default new NamedPage(['problem_create', 'problem_edit'], () => {
buildCategoryFilter();
parseCategorySelection();
async function handleClickUpload() {
const input = document.createElement('input');
input.type = 'file';
input.multiple = true;
input.click();
await new Promise((resolve) => { input.onchange = resolve; });
await uploadFiles('./files', input.files, {
type: 'additional_file',
sidebar: true,
pjax: true,
});
}
async function handleClickRename(ev) {
const file = [$(ev.currentTarget).parent().parent().attr('data-filename')];
// eslint-disable-next-line no-alert
const newName = prompt(i18n('Enter a new name for the file: '));
if (!newName) return;
try {
await request.post('./files', {
operation: 'rename_files',
files: file,
newNames: [newName],
type: 'additional_file',
});
Notification.success(i18n('File have been renamed.'));
await pjax.request({ url: './files?d=additional_file&sidebar=true', push: false });
} catch (error) {
Notification.error(error.message);
}
}
async function handleClickRemove(ev) {
const file = [$(ev.currentTarget).parent().parent().attr('data-filename')];
const action = await new ConfirmDialog({
$body: tpl.typoMsg(i18n('Confirm to delete the file?')),
}).open();
if (action !== 'yes') return;
try {
await request.post('./files', {
operation: 'delete_files',
files: file,
type: 'additional_file',
});
Notification.success(i18n('File have been deleted.'));
await pjax.request({ url: './files?d=additional_file&sidebar=true', push: false });
} catch (error) {
Notification.error(error.message);
}
}
async function handleClickDownloadAll() {
const files = $('.additional_file-table tr').map(function () { return $(this).attr('data-filename'); }).get();
const { links, pdoc } = await request.post('./files', { operation: 'get_links', files, type: 'additional_file' });
const targets = [];
for (const filename of Object.keys(links)) targets.push({ filename, url: links[filename] });
await download(`${pdoc.docId} ${pdoc.title}.zip`, targets);
}
const $main = $('textarea[data-editor]');
const $field = $('textarea[data-markdown-upload]');
let content = $field.val();
@@ -294,12 +210,4 @@ export default new NamedPage(['problem_create', 'problem_edit'], () => {
ev.preventDefault();
}
});
$(document).on('click', '[name="additional_file__upload"]', () => handleClickUpload());
$(document).on('click', '[name="additional_file__rename"]', (ev) => handleClickRename(ev));
$(document).on('click', '[name="additional_file__delete"]', (ev) => handleClickRemove(ev));
$(document).on('click', '[name="additional_file__download"]', () => handleClickDownloadAll());
$(document).on('click', '[name="additional_file__section__expand"]', (ev) => handleSection(ev, 'additional_file', 'expand'));
$(document).on('click', '[name="additional_file__section__collapse"]', (ev) => handleSection(ev, 'additional_file', 'collapse'));
$(document).on('click', '[name="tags__section__expand"]', (ev) => handleSection(ev, 'tags', 'expand'));
$(document).on('click', '[name="tags__section__collapse"]', (ev) => handleSection(ev, 'tags', 'collapse'));
});