mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 14:04:20 +01:00
Adding sortable columns to admin panel (#1337)
* Columns can opt-in to being sortable with the `sort-col` class on `th` elements * Add checkboxes to main admin panels and convert per-line actions into bulk actions
This commit is contained in:
@@ -66,3 +66,11 @@ tbody tr:hover {
|
||||
tr[data-href] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sort-col {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import "./main";
|
||||
import CTFd from "core/CTFd";
|
||||
import $ from "jquery";
|
||||
import { ezAlert, ezQuery } from "core/ezq";
|
||||
|
||||
function deleteSelectedChallenges(event) {
|
||||
let challengeIDs = $("input[data-challenge-id]:checked").map(function() {
|
||||
return $(this).data("challenge-id");
|
||||
});
|
||||
let target = challengeIDs.length === 1 ? "challenge" : "challenges";
|
||||
|
||||
ezQuery({
|
||||
title: "Delete Challenges",
|
||||
body: `Are you sure you want to delete ${challengeIDs.length} ${target}?`,
|
||||
success: function() {
|
||||
const reqs = [];
|
||||
for (var chalID of challengeIDs) {
|
||||
reqs.push(
|
||||
CTFd.fetch(`/api/v1/challenges/${chalID}`, {
|
||||
method: "DELETE"
|
||||
})
|
||||
);
|
||||
}
|
||||
Promise.all(reqs).then(responses => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bulkEditChallenges(event) {
|
||||
let challengeIDs = $("input[data-challenge-id]:checked").map(function() {
|
||||
return $(this).data("challenge-id");
|
||||
});
|
||||
|
||||
ezAlert({
|
||||
title: "Edit Challenges",
|
||||
body: $(`
|
||||
<form id="challenges-bulk-edit">
|
||||
<div class="form-group">
|
||||
<label>Category</label>
|
||||
<input type="text" name="category" data-initial="" value="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Value</label>
|
||||
<input type="number" name="value" data-initial="" value="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>State</label>
|
||||
<select name="state" data-initial="">
|
||||
<option value="">--</option>
|
||||
<option value="visible">Visible</option>
|
||||
<option value="hidden">Hidden</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
`),
|
||||
button: "Submit",
|
||||
success: function() {
|
||||
let data = $("#challenges-bulk-edit").serializeJSON(true);
|
||||
const reqs = [];
|
||||
for (var chalID of challengeIDs) {
|
||||
reqs.push(
|
||||
CTFd.fetch(`/api/v1/challenges/${chalID}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
);
|
||||
}
|
||||
Promise.all(reqs).then(responses => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(() => {
|
||||
$("#challenges-delete-button").click(deleteSelectedChallenges);
|
||||
$("#challenges-edit-button").click(bulkEditChallenges);
|
||||
});
|
||||
|
||||
@@ -1,37 +1,33 @@
|
||||
import "./main";
|
||||
import CTFd from "core/CTFd";
|
||||
import $ from "jquery";
|
||||
import { htmlEntities } from "core/utils";
|
||||
import { ezQuery } from "core/ezq";
|
||||
|
||||
function deletePage(event) {
|
||||
const elem = $(this);
|
||||
const name = elem.attr("page-route");
|
||||
const page_id = elem.attr("page-id");
|
||||
function deleteSelectedUsers(event) {
|
||||
let pageIDs = $("input[data-page-id]:checked").map(function() {
|
||||
return $(this).data("page-id");
|
||||
});
|
||||
let target = pageIDs.length === 1 ? "page" : "pages";
|
||||
|
||||
ezQuery({
|
||||
title: "Delete " + htmlEntities(name),
|
||||
body: "Are you sure you want to delete {0}?".format(
|
||||
"<strong>" + htmlEntities(name) + "</strong>"
|
||||
),
|
||||
title: "Delete Pages",
|
||||
body: `Are you sure you want to delete ${pageIDs.length} ${target}?`,
|
||||
success: function() {
|
||||
CTFd.fetch("/api/v1/pages/" + page_id, {
|
||||
method: "DELETE"
|
||||
})
|
||||
.then(function(response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function(response) {
|
||||
if (response.success) {
|
||||
elem
|
||||
.parent()
|
||||
.parent()
|
||||
.remove();
|
||||
}
|
||||
});
|
||||
const reqs = [];
|
||||
for (var pageID of pageIDs) {
|
||||
reqs.push(
|
||||
CTFd.fetch(`/api/v1/pages/${pageID}`, {
|
||||
method: "DELETE"
|
||||
})
|
||||
);
|
||||
}
|
||||
Promise.all(reqs).then(responses => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(() => {
|
||||
$(".delete-page").click(deletePage);
|
||||
$("#pages-delete-button").click(deleteSelectedUsers);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import "./main";
|
||||
import CTFd from "core/CTFd";
|
||||
import $ from "jquery";
|
||||
import { ezAlert, ezQuery } from "core/ezq";
|
||||
|
||||
const api_func = {
|
||||
users: (x, y) => CTFd.api.patch_user_public({ userId: x }, y),
|
||||
@@ -37,6 +38,48 @@ function toggleAccount() {
|
||||
});
|
||||
}
|
||||
|
||||
function toggleSelectedAccounts(accountIDs, action) {
|
||||
const params = {
|
||||
hidden: action === "hidden" ? true : false
|
||||
};
|
||||
const reqs = [];
|
||||
for (var accId of accountIDs) {
|
||||
reqs.push(api_func[CTFd.config.userMode](accId, params));
|
||||
}
|
||||
Promise.all(reqs).then(responses => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
|
||||
function bulkToggleAccounts(event) {
|
||||
let accountIDs = $("input[data-account-id]:checked").map(function() {
|
||||
return $(this).data("account-id");
|
||||
});
|
||||
|
||||
ezAlert({
|
||||
title: "Toggle Visibility",
|
||||
body: $(`
|
||||
<form id="scoreboard-bulk-edit">
|
||||
<div class="form-group">
|
||||
<label>Visibility</label>
|
||||
<select name="visibility" data-initial="">
|
||||
<option value="">--</option>
|
||||
<option value="visible">Visible</option>
|
||||
<option value="hidden">Hidden</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
`),
|
||||
button: "Submit",
|
||||
success: function() {
|
||||
let data = $("#scoreboard-bulk-edit").serializeJSON(true);
|
||||
let state = data.visibility;
|
||||
toggleSelectedAccounts(accountIDs, state);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(() => {
|
||||
$(".scoreboard-toggle").click(toggleAccount);
|
||||
$("#scoreboard-edit-button").click(bulkToggleAccounts);
|
||||
});
|
||||
|
||||
@@ -40,6 +40,28 @@ function deleteCorrectSubmission(event) {
|
||||
});
|
||||
}
|
||||
|
||||
function deleteSelectedSubmissions(event) {
|
||||
let submissionIDs = $("input[data-submission-id]:checked").map(function() {
|
||||
return $(this).data("submission-id");
|
||||
});
|
||||
let target = submissionIDs.length === 1 ? "submission" : "submissions";
|
||||
|
||||
ezQuery({
|
||||
title: "Delete Submissions",
|
||||
body: `Are you sure you want to delete ${submissionIDs.length} ${target}?`,
|
||||
success: function() {
|
||||
const reqs = [];
|
||||
for (var subId of submissionIDs) {
|
||||
reqs.push(CTFd.api.delete_submission({ submissionId: subId }));
|
||||
}
|
||||
Promise.all(reqs).then(responses => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(() => {
|
||||
$(".delete-correct-submission").click(deleteCorrectSubmission);
|
||||
$("#submission-delete-button").click(deleteSelectedSubmissions);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
import "./main";
|
||||
import CTFd from "core/CTFd";
|
||||
import $ from "jquery";
|
||||
import { ezAlert, ezQuery } from "core/ezq";
|
||||
|
||||
function deleteSelectedTeams(event) {
|
||||
let teamIDs = $("input[data-team-id]:checked").map(function() {
|
||||
return $(this).data("team-id");
|
||||
});
|
||||
let target = teamIDs.length === 1 ? "team" : "teams";
|
||||
|
||||
ezQuery({
|
||||
title: "Delete Teams",
|
||||
body: `Are you sure you want to delete ${teamIDs.length} ${target}?`,
|
||||
success: function() {
|
||||
const reqs = [];
|
||||
for (var teamID of teamIDs) {
|
||||
reqs.push(
|
||||
CTFd.fetch(`/api/v1/teams/${teamID}`, {
|
||||
method: "DELETE"
|
||||
})
|
||||
);
|
||||
}
|
||||
Promise.all(reqs).then(responses => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bulkEditTeams(event) {
|
||||
let teamIDs = $("input[data-team-id]:checked").map(function() {
|
||||
return $(this).data("team-id");
|
||||
});
|
||||
|
||||
ezAlert({
|
||||
title: "Edit Teams",
|
||||
body: $(`
|
||||
<form id="teams-bulk-edit">
|
||||
<div class="form-group">
|
||||
<label>Banned</label>
|
||||
<select name="banned" data-initial="">
|
||||
<option value="">--</option>
|
||||
<option value="true">True</option>
|
||||
<option value="false">False</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Hidden</label>
|
||||
<select name="hidden" data-initial="">
|
||||
<option value="">--</option>
|
||||
<option value="true">True</option>
|
||||
<option value="false">False</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
`),
|
||||
button: "Submit",
|
||||
success: function() {
|
||||
let data = $("#teams-bulk-edit").serializeJSON(true);
|
||||
const reqs = [];
|
||||
for (var teamID of teamIDs) {
|
||||
reqs.push(
|
||||
CTFd.fetch(`/api/v1/teams/${teamID}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
);
|
||||
}
|
||||
Promise.all(reqs).then(responses => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(() => {
|
||||
$("#teams-delete-button").click(deleteSelectedTeams);
|
||||
$("#teams-edit-button").click(bulkEditTeams);
|
||||
});
|
||||
|
||||
@@ -1 +1,88 @@
|
||||
import "./main";
|
||||
import CTFd from "core/CTFd";
|
||||
import $ from "jquery";
|
||||
import { ezAlert, ezQuery } from "core/ezq";
|
||||
|
||||
function deleteSelectedUsers(event) {
|
||||
let userIDs = $("input[data-user-id]:checked").map(function() {
|
||||
return $(this).data("user-id");
|
||||
});
|
||||
let target = userIDs.length === 1 ? "user" : "users";
|
||||
|
||||
ezQuery({
|
||||
title: "Delete Users",
|
||||
body: `Are you sure you want to delete ${userIDs.length} ${target}?`,
|
||||
success: function() {
|
||||
const reqs = [];
|
||||
for (var userID of userIDs) {
|
||||
reqs.push(
|
||||
CTFd.fetch(`/api/v1/users/${userID}`, {
|
||||
method: "DELETE"
|
||||
})
|
||||
);
|
||||
}
|
||||
Promise.all(reqs).then(responses => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bulkEditUsers(event) {
|
||||
let userIDs = $("input[data-user-id]:checked").map(function() {
|
||||
return $(this).data("user-id");
|
||||
});
|
||||
|
||||
ezAlert({
|
||||
title: "Edit Users",
|
||||
body: $(`
|
||||
<form id="users-bulk-edit">
|
||||
<div class="form-group">
|
||||
<label>Verified</label>
|
||||
<select name="verified" data-initial="">
|
||||
<option value="">--</option>
|
||||
<option value="true">True</option>
|
||||
<option value="false">False</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Banned</label>
|
||||
<select name="banned" data-initial="">
|
||||
<option value="">--</option>
|
||||
<option value="true">True</option>
|
||||
<option value="false">False</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Hidden</label>
|
||||
<select name="hidden" data-initial="">
|
||||
<option value="">--</option>
|
||||
<option value="true">True</option>
|
||||
<option value="false">False</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
`),
|
||||
button: "Submit",
|
||||
success: function() {
|
||||
let data = $("#users-bulk-edit").serializeJSON(true);
|
||||
const reqs = [];
|
||||
for (var userID of userIDs) {
|
||||
reqs.push(
|
||||
CTFd.fetch(`/api/v1/users/${userID}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
);
|
||||
}
|
||||
Promise.all(reqs).then(responses => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(() => {
|
||||
$("#users-delete-button").click(deleteSelectedUsers);
|
||||
$("#users-edit-button").click(bulkEditUsers);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import "bootstrap/dist/js/bootstrap.bundle";
|
||||
import { makeSortableTables } from "core/utils";
|
||||
import $ from "jquery";
|
||||
|
||||
export default () => {
|
||||
@@ -45,6 +46,27 @@ export default () => {
|
||||
return false;
|
||||
});
|
||||
|
||||
$("[data-checkbox]").click(function(e) {
|
||||
if ($(e.target).is("input[type=checkbox]")) {
|
||||
e.stopImmediatePropagation();
|
||||
return;
|
||||
}
|
||||
let checkbox = $(this).find("input[type=checkbox]");
|
||||
// Doing it this way with an event allows data-checkbox-all to work
|
||||
checkbox.click();
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
|
||||
$("[data-checkbox-all]").on("click change", function(e) {
|
||||
const checked = $(this).prop("checked");
|
||||
const idx = $(this).index() + 1;
|
||||
$(this)
|
||||
.closest("table")
|
||||
.find(`tr td:nth-child(${idx}) input[type=checkbox]`)
|
||||
.prop("checked", checked);
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
|
||||
$("tr[data-href] a, tr[data-href] button").click(function(e) {
|
||||
// TODO: This is a hack to allow modal close buttons to work
|
||||
if (!$(this).attr("data-dismiss")) {
|
||||
@@ -52,6 +74,7 @@ export default () => {
|
||||
}
|
||||
});
|
||||
|
||||
makeSortableTables();
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:1px;width:100%;height:60px;line-height:normal !important;z-index:-20}
|
||||
|
||||
#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#keys-pie-graph{height:400px;display:block}#categories-pie-graph{height:400px;display:block}#solve-percentages-graph{height:400px;display:block}.no-decoration{color:inherit !important;text-decoration:none !important}.no-decoration:hover{color:inherit !important;text-decoration:none !important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:"Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,0.1) !important}tr[data-href]{cursor:pointer}
|
||||
#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#keys-pie-graph{height:400px;display:block}#categories-pie-graph{height:400px;display:block}#solve-percentages-graph{height:400px;display:block}.no-decoration{color:inherit !important;text-decoration:none !important}.no-decoration:hover{color:inherit !important;text-decoration:none !important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:"Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,0.1) !important}tr[data-href]{cursor:pointer}.sort-col{cursor:pointer}input[type="checkbox"]{cursor:pointer}
|
||||
|
||||
|
||||
2
CTFd/themes/admin/static/css/admin.min.css
vendored
2
CTFd/themes/admin/static/css/admin.min.css
vendored
@@ -1 +1 @@
|
||||
html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:1px;width:100%;height:60px;line-height:normal!important;z-index:-20}#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#categories-pie-graph,#keys-pie-graph,#solve-percentages-graph{height:400px;display:block}.no-decoration,.no-decoration:hover{color:inherit!important;text-decoration:none!important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:Avenir Next,Helvetica Neue,Helvetica,Arial,sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,.1)!important}tr[data-href]{cursor:pointer}
|
||||
html{position:relative;min-height:100%}body{margin-bottom:60px}.footer{position:absolute;bottom:1px;width:100%;height:60px;line-height:normal!important;z-index:-20}#score-graph{height:450px;display:block;clear:both}#solves-graph{display:block;height:350px}#categories-pie-graph,#keys-pie-graph,#solve-percentages-graph{height:400px;display:block}.no-decoration,.no-decoration:hover{color:inherit!important;text-decoration:none!important}.table td,.table th{vertical-align:inherit}pre{white-space:pre-wrap;margin:0;padding:0}.form-control{position:relative;display:block;border-radius:0;font-weight:400;font-family:Avenir Next,Helvetica Neue,Helvetica,Arial,sans-serif;-webkit-appearance:none}tbody tr:hover{background-color:rgba(0,0,0,.1)!important}.sort-col,input[type=checkbox],tr[data-href]{cursor:pointer}
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/challenge.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/challenge.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
|
||||
File diff suppressed because one or more lines are too long
169
CTFd/themes/admin/static/js/pages/challenges.dev.js
Normal file
169
CTFd/themes/admin/static/js/pages/challenges.dev.js
Normal file
@@ -0,0 +1,169 @@
|
||||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // install a JSONP callback for chunk loading
|
||||
/******/ function webpackJsonpCallback(data) {
|
||||
/******/ var chunkIds = data[0];
|
||||
/******/ var moreModules = data[1];
|
||||
/******/ var executeModules = data[2];
|
||||
/******/
|
||||
/******/ // add "moreModules" to the modules object,
|
||||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||
/******/ var moduleId, chunkId, i = 0, resolves = [];
|
||||
/******/ for(;i < chunkIds.length; i++) {
|
||||
/******/ chunkId = chunkIds[i];
|
||||
/******/ if(installedChunks[chunkId]) {
|
||||
/******/ resolves.push(installedChunks[chunkId][0]);
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ for(moduleId in moreModules) {
|
||||
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
|
||||
/******/ modules[moduleId] = moreModules[moduleId];
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
|
||||
/******/
|
||||
/******/ while(resolves.length) {
|
||||
/******/ resolves.shift()();
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // add entry modules from loaded chunk to deferred list
|
||||
/******/ deferredModules.push.apply(deferredModules, executeModules || []);
|
||||
/******/
|
||||
/******/ // run deferred modules when all chunks ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ };
|
||||
/******/ function checkDeferredModules() {
|
||||
/******/ var result;
|
||||
/******/ for(var i = 0; i < deferredModules.length; i++) {
|
||||
/******/ var deferredModule = deferredModules[i];
|
||||
/******/ var fulfilled = true;
|
||||
/******/ for(var j = 1; j < deferredModule.length; j++) {
|
||||
/******/ var depId = deferredModule[j];
|
||||
/******/ if(installedChunks[depId] !== 0) fulfilled = false;
|
||||
/******/ }
|
||||
/******/ if(fulfilled) {
|
||||
/******/ deferredModules.splice(i--, 1);
|
||||
/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ return result;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // object to store loaded and loading chunks
|
||||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||||
/******/ // Promise = chunk loading, 0 = chunk loaded
|
||||
/******/ var installedChunks = {
|
||||
/******/ "pages/challenges": 0
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ var deferredModules = [];
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = function(exports) {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // create a fake namespace object
|
||||
/******/ // mode & 1: value is a module id, require it
|
||||
/******/ // mode & 2: merge all properties of value into the ns
|
||||
/******/ // mode & 4: return value when already ns object
|
||||
/******/ // mode & 8|1: behave like require
|
||||
/******/ __webpack_require__.t = function(value, mode) {
|
||||
/******/ if(mode & 1) value = __webpack_require__(value);
|
||||
/******/ if(mode & 8) return value;
|
||||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||||
/******/ var ns = Object.create(null);
|
||||
/******/ __webpack_require__.r(ns);
|
||||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||||
/******/ return ns;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "/themes/admin/static/js";
|
||||
/******/
|
||||
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
|
||||
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
|
||||
/******/ jsonpArray.push = webpackJsonpCallback;
|
||||
/******/ jsonpArray = jsonpArray.slice();
|
||||
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
|
||||
/******/ var parentJsonpFunction = oldJsonpFunction;
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/challenges.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ({
|
||||
|
||||
/***/ "./CTFd/themes/admin/assets/js/pages/challenges.js":
|
||||
/*!*********************************************************!*\
|
||||
!*** ./CTFd/themes/admin/assets/js/pages/challenges.js ***!
|
||||
\*********************************************************/
|
||||
/*! no static exports found */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
;
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteSelectedChallenges(event) {\n var challengeIDs = (0, _jquery.default)(\"input[data-challenge-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"challenge-id\");\n });\n var target = challengeIDs.length === 1 ? \"challenge\" : \"challenges\";\n (0, _ezq.ezQuery)({\n title: \"Delete Challenges\",\n body: \"Are you sure you want to delete \".concat(challengeIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = challengeIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var chalID = _step.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/challenges/\".concat(chalID), {\n method: \"DELETE\"\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\nfunction bulkEditChallenges(event) {\n var challengeIDs = (0, _jquery.default)(\"input[data-challenge-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"challenge-id\");\n });\n (0, _ezq.ezAlert)({\n title: \"Edit Challenges\",\n body: (0, _jquery.default)(\"\\n <form id=\\\"challenges-bulk-edit\\\">\\n <div class=\\\"form-group\\\">\\n <label>Category</label>\\n <input type=\\\"text\\\" name=\\\"category\\\" data-initial=\\\"\\\" value=\\\"\\\">\\n </div>\\n <div class=\\\"form-group\\\">\\n <label>Value</label>\\n <input type=\\\"number\\\" name=\\\"value\\\" data-initial=\\\"\\\" value=\\\"\\\">\\n </div>\\n <div class=\\\"form-group\\\">\\n <label>State</label>\\n <select name=\\\"state\\\" data-initial=\\\"\\\">\\n <option value=\\\"\\\">--</option>\\n <option value=\\\"visible\\\">Visible</option>\\n <option value=\\\"hidden\\\">Hidden</option>\\n </select>\\n </div>\\n </form>\\n \"),\n button: \"Submit\",\n success: function success() {\n var data = (0, _jquery.default)(\"#challenges-bulk-edit\").serializeJSON(true);\n var reqs = [];\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = challengeIDs[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var chalID = _step2.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/challenges/\".concat(chalID), {\n method: \"PATCH\",\n body: JSON.stringify(data)\n }));\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return != null) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\"#challenges-delete-button\").click(deleteSelectedChallenges);\n (0, _jquery.default)(\"#challenges-edit-button\").click(bulkEditChallenges);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/challenges.js?");
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
1
CTFd/themes/admin/static/js/pages/challenges.min.js
vendored
Normal file
1
CTFd/themes/admin/static/js/pages/challenges.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/configs.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/configs.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/editor.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/editor.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/main.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/main.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/notifications.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/notifications.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/pages.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/pages.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
@@ -162,7 +162,7 @@
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
;
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deletePage(event) {\n var elem = (0, _jquery.default)(this);\n var name = elem.attr(\"page-route\");\n var page_id = elem.attr(\"page-id\");\n (0, _ezq.ezQuery)({\n title: \"Delete \" + (0, _utils.htmlEntities)(name),\n body: \"Are you sure you want to delete {0}?\".format(\"<strong>\" + (0, _utils.htmlEntities)(name) + \"</strong>\"),\n success: function success() {\n _CTFd.default.fetch(\"/api/v1/pages/\" + page_id, {\n method: \"DELETE\"\n }).then(function (response) {\n return response.json();\n }).then(function (response) {\n if (response.success) {\n elem.parent().parent().remove();\n }\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".delete-page\").click(deletePage);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/pages.js?");
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteSelectedUsers(event) {\n var pageIDs = (0, _jquery.default)(\"input[data-page-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"page-id\");\n });\n var target = pageIDs.length === 1 ? \"page\" : \"pages\";\n (0, _ezq.ezQuery)({\n title: \"Delete Pages\",\n body: \"Are you sure you want to delete \".concat(pageIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = pageIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var pageID = _step.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/pages/\".concat(pageID), {\n method: \"DELETE\"\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\"#pages-delete-button\").click(deleteSelectedUsers);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/pages.js?");
|
||||
|
||||
/***/ })
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/reset.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/reset.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/scoreboard.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/scoreboard.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
@@ -162,7 +162,7 @@
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
;
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar api_func = {\n users: function users(x, y) {\n return _CTFd.default.api.patch_user_public({\n userId: x\n }, y);\n },\n teams: function teams(x, y) {\n return _CTFd.default.api.patch_team_public({\n teamId: x\n }, y);\n }\n};\n\nfunction toggleAccount() {\n var $btn = (0, _jquery.default)(this);\n var id = $btn.data(\"account-id\");\n var state = $btn.data(\"state\");\n var hidden = undefined;\n\n if (state === \"visible\") {\n hidden = true;\n } else if (state === \"hidden\") {\n hidden = false;\n }\n\n var params = {\n hidden: hidden\n };\n\n api_func[_CTFd.default.config.userMode](id, params).then(function (response) {\n if (response.success) {\n if (hidden) {\n $btn.data(\"state\", \"hidden\");\n $btn.addClass(\"btn-danger\").removeClass(\"btn-success\");\n $btn.text(\"Hidden\");\n } else {\n $btn.data(\"state\", \"visible\");\n $btn.addClass(\"btn-success\").removeClass(\"btn-danger\");\n $btn.text(\"Visible\");\n }\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".scoreboard-toggle\").click(toggleAccount);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/scoreboard.js?");
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar api_func = {\n users: function users(x, y) {\n return _CTFd.default.api.patch_user_public({\n userId: x\n }, y);\n },\n teams: function teams(x, y) {\n return _CTFd.default.api.patch_team_public({\n teamId: x\n }, y);\n }\n};\n\nfunction toggleAccount() {\n var $btn = (0, _jquery.default)(this);\n var id = $btn.data(\"account-id\");\n var state = $btn.data(\"state\");\n var hidden = undefined;\n\n if (state === \"visible\") {\n hidden = true;\n } else if (state === \"hidden\") {\n hidden = false;\n }\n\n var params = {\n hidden: hidden\n };\n\n api_func[_CTFd.default.config.userMode](id, params).then(function (response) {\n if (response.success) {\n if (hidden) {\n $btn.data(\"state\", \"hidden\");\n $btn.addClass(\"btn-danger\").removeClass(\"btn-success\");\n $btn.text(\"Hidden\");\n } else {\n $btn.data(\"state\", \"visible\");\n $btn.addClass(\"btn-success\").removeClass(\"btn-danger\");\n $btn.text(\"Visible\");\n }\n }\n });\n}\n\nfunction toggleSelectedAccounts(accountIDs, action) {\n var params = {\n hidden: action === \"hidden\" ? true : false\n };\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = accountIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var accId = _step.value;\n reqs.push(api_func[_CTFd.default.config.userMode](accId, params));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n}\n\nfunction bulkToggleAccounts(event) {\n var accountIDs = (0, _jquery.default)(\"input[data-account-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"account-id\");\n });\n (0, _ezq.ezAlert)({\n title: \"Toggle Visibility\",\n body: (0, _jquery.default)(\"\\n <form id=\\\"scoreboard-bulk-edit\\\">\\n <div class=\\\"form-group\\\">\\n <label>Visibility</label>\\n <select name=\\\"visibility\\\" data-initial=\\\"\\\">\\n <option value=\\\"\\\">--</option>\\n <option value=\\\"visible\\\">Visible</option>\\n <option value=\\\"hidden\\\">Hidden</option>\\n </select>\\n </div>\\n </form>\\n \"),\n button: \"Submit\",\n success: function success() {\n var data = (0, _jquery.default)(\"#scoreboard-bulk-edit\").serializeJSON(true);\n var state = data.visibility;\n toggleSelectedAccounts(accountIDs, state);\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".scoreboard-toggle\").click(toggleAccount);\n (0, _jquery.default)(\"#scoreboard-edit-button\").click(bulkToggleAccounts);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/scoreboard.js?");
|
||||
|
||||
/***/ })
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/statistics.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/statistics.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/submissions.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/submissions.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
@@ -162,7 +162,7 @@
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
;
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteCorrectSubmission(event) {\n var key_id = (0, _jquery.default)(this).data(\"submission-id\");\n var $elem = (0, _jquery.default)(this).parent().parent();\n var chal_name = $elem.find(\".chal\").text().trim();\n var team_name = $elem.find(\".team\").text().trim();\n var row = (0, _jquery.default)(this).parent().parent();\n (0, _ezq.ezQuery)({\n title: \"Delete Submission\",\n body: \"Are you sure you want to delete correct submission from {0} for challenge {1}\".format(\"<strong>\" + (0, _utils.htmlEntities)(team_name) + \"</strong>\", \"<strong>\" + (0, _utils.htmlEntities)(chal_name) + \"</strong>\"),\n success: function success() {\n _CTFd.default.api.delete_submission({\n submissionId: key_id\n }).then(function (response) {\n if (response.success) {\n row.remove();\n }\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".delete-correct-submission\").click(deleteCorrectSubmission);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/submissions.js?");
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _utils = __webpack_require__(/*! core/utils */ \"./CTFd/themes/core/assets/js/utils.js\");\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteCorrectSubmission(event) {\n var key_id = (0, _jquery.default)(this).data(\"submission-id\");\n var $elem = (0, _jquery.default)(this).parent().parent();\n var chal_name = $elem.find(\".chal\").text().trim();\n var team_name = $elem.find(\".team\").text().trim();\n var row = (0, _jquery.default)(this).parent().parent();\n (0, _ezq.ezQuery)({\n title: \"Delete Submission\",\n body: \"Are you sure you want to delete correct submission from {0} for challenge {1}\".format(\"<strong>\" + (0, _utils.htmlEntities)(team_name) + \"</strong>\", \"<strong>\" + (0, _utils.htmlEntities)(chal_name) + \"</strong>\"),\n success: function success() {\n _CTFd.default.api.delete_submission({\n submissionId: key_id\n }).then(function (response) {\n if (response.success) {\n row.remove();\n }\n });\n }\n });\n}\n\nfunction deleteSelectedSubmissions(event) {\n var submissionIDs = (0, _jquery.default)(\"input[data-submission-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"submission-id\");\n });\n var target = submissionIDs.length === 1 ? \"submission\" : \"submissions\";\n (0, _ezq.ezQuery)({\n title: \"Delete Submissions\",\n body: \"Are you sure you want to delete \".concat(submissionIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = submissionIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var subId = _step.value;\n reqs.push(_CTFd.default.api.delete_submission({\n submissionId: subId\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\".delete-correct-submission\").click(deleteCorrectSubmission);\n (0, _jquery.default)(\"#submission-delete-button\").click(deleteSelectedSubmissions);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/submissions.js?");
|
||||
|
||||
/***/ })
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/team.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/team.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,66 @@
|
||||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // install a JSONP callback for chunk loading
|
||||
/******/ function webpackJsonpCallback(data) {
|
||||
/******/ var chunkIds = data[0];
|
||||
/******/ var moreModules = data[1];
|
||||
/******/ var executeModules = data[2];
|
||||
/******/
|
||||
/******/ // add "moreModules" to the modules object,
|
||||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||
/******/ var moduleId, chunkId, i = 0, resolves = [];
|
||||
/******/ for(;i < chunkIds.length; i++) {
|
||||
/******/ chunkId = chunkIds[i];
|
||||
/******/ if(installedChunks[chunkId]) {
|
||||
/******/ resolves.push(installedChunks[chunkId][0]);
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ for(moduleId in moreModules) {
|
||||
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
|
||||
/******/ modules[moduleId] = moreModules[moduleId];
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
|
||||
/******/
|
||||
/******/ while(resolves.length) {
|
||||
/******/ resolves.shift()();
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // add entry modules from loaded chunk to deferred list
|
||||
/******/ deferredModules.push.apply(deferredModules, executeModules || []);
|
||||
/******/
|
||||
/******/ // run deferred modules when all chunks ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ };
|
||||
/******/ function checkDeferredModules() {
|
||||
/******/ var result;
|
||||
/******/ for(var i = 0; i < deferredModules.length; i++) {
|
||||
/******/ var deferredModule = deferredModules[i];
|
||||
/******/ var fulfilled = true;
|
||||
/******/ for(var j = 1; j < deferredModule.length; j++) {
|
||||
/******/ var depId = deferredModule[j];
|
||||
/******/ if(installedChunks[depId] !== 0) fulfilled = false;
|
||||
/******/ }
|
||||
/******/ if(fulfilled) {
|
||||
/******/ deferredModules.splice(i--, 1);
|
||||
/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ return result;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // object to store loaded and loading chunks
|
||||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||||
/******/ // Promise = chunk loading, 0 = chunk loaded
|
||||
/******/ var installedChunks = {
|
||||
/******/ "pages/teams": 0
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ var deferredModules = [];
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
@@ -79,9 +138,18 @@
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "/themes/admin/static/js";
|
||||
/******/
|
||||
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
|
||||
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
|
||||
/******/ jsonpArray.push = webpackJsonpCallback;
|
||||
/******/ jsonpArray = jsonpArray.slice();
|
||||
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
|
||||
/******/ var parentJsonpFunction = oldJsonpFunction;
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = "./CTFd/themes/admin/assets/js/pages/teams.js");
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/teams.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ({
|
||||
@@ -94,7 +162,7 @@
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
;
|
||||
eval("\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/teams.js?");
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteSelectedTeams(event) {\n var teamIDs = (0, _jquery.default)(\"input[data-team-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"team-id\");\n });\n var target = teamIDs.length === 1 ? \"team\" : \"teams\";\n (0, _ezq.ezQuery)({\n title: \"Delete Teams\",\n body: \"Are you sure you want to delete \".concat(teamIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = teamIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var teamID = _step.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/teams/\".concat(teamID), {\n method: \"DELETE\"\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\nfunction bulkEditTeams(event) {\n var teamIDs = (0, _jquery.default)(\"input[data-team-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"team-id\");\n });\n (0, _ezq.ezAlert)({\n title: \"Edit Teams\",\n body: (0, _jquery.default)(\"\\n <form id=\\\"teams-bulk-edit\\\">\\n <div class=\\\"form-group\\\">\\n <label>Banned</label>\\n <select name=\\\"banned\\\" data-initial=\\\"\\\">\\n <option value=\\\"\\\">--</option>\\n <option value=\\\"true\\\">True</option>\\n <option value=\\\"false\\\">False</option>\\n </select>\\n </div>\\n <div class=\\\"form-group\\\">\\n <label>Hidden</label>\\n <select name=\\\"hidden\\\" data-initial=\\\"\\\">\\n <option value=\\\"\\\">--</option>\\n <option value=\\\"true\\\">True</option>\\n <option value=\\\"false\\\">False</option>\\n </select>\\n </div>\\n </form>\\n \"),\n button: \"Submit\",\n success: function success() {\n var data = (0, _jquery.default)(\"#teams-bulk-edit\").serializeJSON(true);\n var reqs = [];\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = teamIDs[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var teamID = _step2.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/teams/\".concat(teamID), {\n method: \"PATCH\",\n body: JSON.stringify(data)\n }));\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return != null) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\"#teams-delete-button\").click(deleteSelectedTeams);\n (0, _jquery.default)(\"#teams-edit-button\").click(bulkEditTeams);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/teams.js?");
|
||||
|
||||
/***/ })
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/user.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/user.js","helpers","graphs","plotly","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,7 +147,7 @@
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add entry module to deferred list
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/users.js","helpers","vendor","default~pages/challenge~pages/configs~pages/editor~pages/main~pages/notifications~pages/pages~pages/~0fc9fcae"]);
|
||||
/******/ deferredModules.push(["./CTFd/themes/admin/assets/js/pages/users.js","helpers","vendor","default~pages/challenge~pages/challenges~pages/configs~pages/editor~pages/main~pages/notifications~p~d5a3cc0a"]);
|
||||
/******/ // run deferred modules when ready
|
||||
/******/ return checkDeferredModules();
|
||||
/******/ })
|
||||
@@ -162,7 +162,7 @@
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
;
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/users.js?");
|
||||
eval("\n\n__webpack_require__(/*! ./main */ \"./CTFd/themes/admin/assets/js/pages/main.js\");\n\nvar _CTFd = _interopRequireDefault(__webpack_require__(/*! core/CTFd */ \"./CTFd/themes/core/assets/js/CTFd.js\"));\n\nvar _jquery = _interopRequireDefault(__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"));\n\nvar _ezq = __webpack_require__(/*! core/ezq */ \"./CTFd/themes/core/assets/js/ezq.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction deleteSelectedUsers(event) {\n var userIDs = (0, _jquery.default)(\"input[data-user-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"user-id\");\n });\n var target = userIDs.length === 1 ? \"user\" : \"users\";\n (0, _ezq.ezQuery)({\n title: \"Delete Users\",\n body: \"Are you sure you want to delete \".concat(userIDs.length, \" \").concat(target, \"?\"),\n success: function success() {\n var reqs = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = userIDs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var userID = _step.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/users/\".concat(userID), {\n method: \"DELETE\"\n }));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\nfunction bulkEditUsers(event) {\n var userIDs = (0, _jquery.default)(\"input[data-user-id]:checked\").map(function () {\n return (0, _jquery.default)(this).data(\"user-id\");\n });\n (0, _ezq.ezAlert)({\n title: \"Edit Users\",\n body: (0, _jquery.default)(\"\\n <form id=\\\"users-bulk-edit\\\">\\n <div class=\\\"form-group\\\">\\n <label>Verified</label>\\n <select name=\\\"verified\\\" data-initial=\\\"\\\">\\n <option value=\\\"\\\">--</option>\\n <option value=\\\"true\\\">True</option>\\n <option value=\\\"false\\\">False</option>\\n </select>\\n </div>\\n <div class=\\\"form-group\\\">\\n <label>Banned</label>\\n <select name=\\\"banned\\\" data-initial=\\\"\\\">\\n <option value=\\\"\\\">--</option>\\n <option value=\\\"true\\\">True</option>\\n <option value=\\\"false\\\">False</option>\\n </select>\\n </div>\\n <div class=\\\"form-group\\\">\\n <label>Hidden</label>\\n <select name=\\\"hidden\\\" data-initial=\\\"\\\">\\n <option value=\\\"\\\">--</option>\\n <option value=\\\"true\\\">True</option>\\n <option value=\\\"false\\\">False</option>\\n </select>\\n </div>\\n </form>\\n \"),\n button: \"Submit\",\n success: function success() {\n var data = (0, _jquery.default)(\"#users-bulk-edit\").serializeJSON(true);\n var reqs = [];\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = userIDs[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var userID = _step2.value;\n reqs.push(_CTFd.default.fetch(\"/api/v1/users/\".concat(userID), {\n method: \"PATCH\",\n body: JSON.stringify(data)\n }));\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return != null) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n Promise.all(reqs).then(function (responses) {\n window.location.reload();\n });\n }\n });\n}\n\n(0, _jquery.default)(function () {\n (0, _jquery.default)(\"#users-delete-button\").click(deleteSelectedUsers);\n (0, _jquery.default)(\"#users-edit-button\").click(bulkEditUsers);\n});\n\n//# sourceURL=webpack:///./CTFd/themes/admin/assets/js/pages/users.js?");
|
||||
|
||||
/***/ })
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -18,28 +18,53 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="float-right pb-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary" data-toggle="tooltip" title="Edit Challenges" id="challenges-edit-button">
|
||||
<i class="btn-fa fas fa-pencil-alt"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-danger" data-toggle="tooltip" title="Delete Challenges" id="challenges-delete-button">
|
||||
<i class="btn-fa fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div>
|
||||
<table id="challenges" class="table table-striped">
|
||||
<table id="challenges" class="table table-striped border">
|
||||
<thead>
|
||||
<tr>
|
||||
<td><b>ID</b></td>
|
||||
<td><b>Name</b></td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell"><b>Category</b></td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell"><b>Value</b></td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell"><b>Type</b></td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell text-center"><b>State</b></td>
|
||||
<td class="d-block border-right border-bottom text-center" data-checkbox>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" data-checkbox-all>
|
||||
</div>
|
||||
</td>
|
||||
<th class="sort-col text-center"><b>ID</b></th>
|
||||
<th class="sort-col"><b>Name</b></th>
|
||||
<th class="d-none d-md-table-cell d-lg-table-cell sort-col"><b>Category</b></th>
|
||||
<th class="d-none d-md-table-cell d-lg-table-cell sort-col text-center"><b>Value</b></th>
|
||||
<th class="d-none d-md-table-cell d-lg-table-cell sort-col text-center"><b>Type</b></th>
|
||||
<th class="d-none d-md-table-cell d-lg-table-cell sort-col text-center"><b>State</b></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for challenge in challenges %}
|
||||
<tr data-href="{{ url_for('admin.challenges_detail', challenge_id=challenge.id) }}">
|
||||
<td>{{ challenge.id }}</td>
|
||||
<td class="d-block border-right text-center" data-checkbox>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" value="{{ challenge.id }}" data-challenge-id="{{ challenge.id }}">
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">{{ challenge.id }}</td>
|
||||
<td><a href="{{ url_for('admin.challenges_detail', challenge_id=challenge.id) }}">{{ challenge.name }}</a></td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell">{{ challenge.category }}</td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell">{{ challenge.value }}</td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell">{{ challenge.type }}</td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell text-center">{{ challenge.value }}</td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell text-center">{{ challenge.type }}</td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell text-center">
|
||||
{% set badge_state = 'badge-danger' if challenge.state == 'hidden' else 'badge-success' %}
|
||||
<span class="badge {{ badge_state }}">{{ challenge.state }}</span>
|
||||
@@ -56,3 +81,7 @@
|
||||
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
|
||||
{% block entrypoint %}
|
||||
<script defer src="{{ url_for('views.themes', theme='admin', path='js/pages/challenges.js') }}"></script>
|
||||
{% endblock %}
|
||||
@@ -19,20 +19,40 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table id="pages" class="table table-striped">
|
||||
<div class="float-right pb-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-outline-danger" data-toggle="tooltip" title="Delete Pages" id="pages-delete-button">
|
||||
<i class="btn-fa fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table id="pages" class="table table-striped border">
|
||||
<thead>
|
||||
<tr>
|
||||
<td><b>Title</b></td>
|
||||
<td><b>Route</b></td>
|
||||
<td class="text-center"><b>Authentication</b></td>
|
||||
<td class="text-center"><b>Hidden</b></td>
|
||||
<td class="text-center"><b>Published</b></td>
|
||||
<td class="text-center" width="10px"><b>Settings</b></td>
|
||||
<th class="border-right" data-checkbox>
|
||||
<div class="form-check text-center">
|
||||
<input type="checkbox" class="form-check-input" id="scoreboard-bulk-select" data-checkbox-all>
|
||||
</div>
|
||||
</th>
|
||||
<th class="sort-col text-center"><b>Title</b></th>
|
||||
<th class="sort-col text-center"><b>Route</b></th>
|
||||
<th class="sort-col text-center"><b>Authentication</b></th>
|
||||
<th class="sort-col text-center"><b>Hidden</b></th>
|
||||
<th class="sort-col text-center"><b>Published</b></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for page in pages %}
|
||||
<tr>
|
||||
<tr data-href="{{ url_for('admin.pages_detail', page_id=page.id) }}">
|
||||
<td class="border-right" data-checkbox>
|
||||
<div class="form-check text-center">
|
||||
<input type="checkbox" class="form-check-input" value="{{ page.id }}" data-page-id="{{ page.id }}">
|
||||
</div>
|
||||
</td>
|
||||
<td class="page-title">
|
||||
{{ page.title }}
|
||||
</td>
|
||||
@@ -60,17 +80,6 @@
|
||||
Published
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span class="edit-page" data-toggle="tooltip" data-placement="top"
|
||||
title="Edit {{ page.route }}">
|
||||
<a class="no-decoration" href="{{ url_for('admin.pages_detail', page_id=page.id) }}"><i class="btn-fa fas fa-edit"></i></a>
|
||||
</span>
|
||||
<span class="delete-page" page-id="{{ page.id }}" page-route="{{ page.route }}"
|
||||
page-title="{{ page.title }}" data-toggle="tooltip" data-placement="top"
|
||||
title="Delete {{ page.route }}">
|
||||
<i class="btn-fa fas fa-times"></i>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@@ -9,19 +9,40 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table id="scoreboard" class="table table-striped">
|
||||
<div class="float-right pb-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary" id="scoreboard-edit-button" data-toggle="tooltip" title="Hide/Unhide Accounts">
|
||||
<i class="btn-fa fas fa-eye"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table id="scoreboard" class="table table-striped border">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="10px"><b>Place</b></td>
|
||||
<td><b>Team</b></td>
|
||||
<td><b>Score</b></td>
|
||||
<td><b>Visibility</b></td>
|
||||
<th class="border-right" data-checkbox>
|
||||
<div class="form-check text-center">
|
||||
<input type="checkbox" class="form-check-input" id="scoreboard-bulk-select" data-checkbox-all>
|
||||
</div>
|
||||
</th>
|
||||
<th class="sort-col text-center"><b>Place</b></th>
|
||||
<th class="sort-col"><b>Team</b></th>
|
||||
<th class="sort-col"><b>Score</b></th>
|
||||
<th class="sort-col"><b>Visibility</b></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for standing in standings %}
|
||||
<tr data-href="{{ generate_account_url(standing.account_id, admin=True) }}">
|
||||
<td>{{ loop.index }}</td>
|
||||
<td class="border-right text-center" data-checkbox>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" value="{{ standing.account_id }}" data-account-id="{{ standing.account_id }}">
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center" width="10%">{{ loop.index }}</td>
|
||||
<td>
|
||||
<a href="{{ generate_account_url(standing.account_id, admin=True) }}">
|
||||
{{ standing.name }}
|
||||
@@ -40,15 +61,11 @@
|
||||
</td>
|
||||
<td>{{ standing.score }}</td>
|
||||
<td>
|
||||
{% if standing.hidden %}
|
||||
<button class="btn-sm btn-danger cursor-pointer scoreboard-toggle" type="submit"
|
||||
data-account-id="{{ standing.account_id }}" data-state="hidden">Hidden
|
||||
</button>
|
||||
{% else %}
|
||||
<button class="btn-sm btn-success cursor-pointer scoreboard-toggle" type="submit"
|
||||
data-account-id="{{ standing.account_id }}" data-state="visible">Visible
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if standing.hidden %}
|
||||
<span class="badge badge-danger">hidden</span>
|
||||
{% else %}
|
||||
<span class="badge badge-success">visible</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
@@ -14,21 +14,41 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table id="teamsboard" class=" table table-striped">
|
||||
<div class="float-right pb-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-outline-danger" id="submission-delete-button">
|
||||
<i class="btn-fa fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table id="teamsboard" class="table table-striped border">
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="text-center"><b>ID</b></td>
|
||||
<td><b>Team</b></td>
|
||||
<td><b>Challenge</b></td>
|
||||
<td><b>Type</b></td>
|
||||
<td><b>Submission</b></td>
|
||||
<td class="text-center"><b>Date</b></td>
|
||||
<td class="text-center"><b>Delete</b></td>
|
||||
<th class="border-right" data-checkbox>
|
||||
<div class="form-check text-center">
|
||||
<input type="checkbox" class="form-check-input" data-checkbox-all>
|
||||
</div>
|
||||
</th>
|
||||
<th class="text-center sort-col"><b>ID</b></th>
|
||||
<th class="sort-col"><b>Team</b></th>
|
||||
<th class="sort-col"><b>Challenge</b></th>
|
||||
<th class="sort-col"><b>Type</b></th>
|
||||
<th class="sort-col"><b>Submission</b></th>
|
||||
<th class="text-center sort-col"><b>Date</b></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for sub in submissions %}
|
||||
<tr>
|
||||
<td class="border-right" data-checkbox>
|
||||
<div class="form-check text-center">
|
||||
<input type="checkbox" class="form-check-input" value="{{ sub.id }}" data-submission-id="{{ sub.id }}">
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center" id="{{ sub.id }}">
|
||||
{{ sub.id }}
|
||||
</td>
|
||||
@@ -36,7 +56,9 @@
|
||||
<a href="{{ generate_account_url(sub.account_id, admin=True) }}">{{ sub.team_name }}</a>
|
||||
</td>
|
||||
<td class="chal" id="{{ sub.challenge_id }}">
|
||||
{{ sub.challenge_name }}
|
||||
<a href="{{ url_for('admin.challenges_detail', challenge_id=sub.challenge_id) }}">
|
||||
{{ sub.challenge_name }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ sub.type }}
|
||||
@@ -47,12 +69,6 @@
|
||||
<td class="text-center solve-time">
|
||||
<span data-time="{{ sub.date | isoformat }}"></span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span class="delete-correct-submission" data-toggle="tooltip"
|
||||
data-placement="top" title="Delete submission #{{ sub.id }}" data-submission-id="{{ sub.id }}">
|
||||
<i class="fas fa-times"></i>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@@ -24,48 +24,71 @@
|
||||
{% endif %}
|
||||
|
||||
<form method="GET" class="form-inline">
|
||||
<div class="form-group col-md-2">
|
||||
<label for="sel1" class="sr-only" >Search Field</label>
|
||||
<select class="form-control custom-select w-100" id="sel1" name="field">
|
||||
<option value="name" {% if field == 'name' %}selected{% endif %}>Name</option>
|
||||
<option value="id" {% if field == 'id' %}selected{% endif %}>ID</option>
|
||||
<option value="email" {% if field == 'email' %}selected{% endif %}>Email</option>
|
||||
<option value="affiliation" {% if field == 'affiliation' %}selected{% endif %}>Affiliation</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-md-8">
|
||||
<label for="team-name-search" class="sr-only">Parameter</label>
|
||||
<input type="text" class="form-control w-100" id="team-name-search" name="q" placeholder="Search for matching team names" {% if q %}value="{{q}}"{% endif %}>
|
||||
</div>
|
||||
<div class="form-group col-md-2">
|
||||
<label for="team-name-search" class="sr-only">Search</label>
|
||||
<button type="submit" class="btn btn-primary w-100"><i class="fas fa-search" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
<div class="form-group col-md-2">
|
||||
<label for="sel1" class="sr-only" >Search Field</label>
|
||||
<select class="form-control custom-select w-100" id="sel1" name="field">
|
||||
<option value="name" {% if field == 'name' %}selected{% endif %}>Name</option>
|
||||
<option value="id" {% if field == 'id' %}selected{% endif %}>ID</option>
|
||||
<option value="email" {% if field == 'email' %}selected{% endif %}>Email</option>
|
||||
<option value="affiliation" {% if field == 'affiliation' %}selected{% endif %}>Affiliation</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-md-8">
|
||||
<label for="team-name-search" class="sr-only">Parameter</label>
|
||||
<input type="text" class="form-control w-100" id="team-name-search" name="q" placeholder="Search for matching team names" {% if q %}value="{{q}}"{% endif %}>
|
||||
</div>
|
||||
<div class="form-group col-md-2">
|
||||
<label for="team-name-search" class="sr-only">Search</label>
|
||||
<button type="submit" class="btn btn-primary w-100"><i class="fas fa-search" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
|
||||
<table id="teamsboard" class="table table-striped">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="float-right pb-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary" data-toggle="tooltip" title="Edit Teams" id="teams-edit-button">
|
||||
<i class="btn-fa fas fa-pencil-alt"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-danger" data-toggle="tooltip" title="Delete Teams" id="teams-delete-button">
|
||||
<i class="btn-fa fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table id="teamsboard" class="table table-striped border">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="10px" class="text-center"><b>ID</b>
|
||||
</td>
|
||||
<td class="text-left"><b>Team</b>
|
||||
</td>
|
||||
<td class="text-center"><b>Website</b>
|
||||
</td>
|
||||
<td class="text-center"><b>Country</b>
|
||||
</td>
|
||||
<td class="text-center"><b>Hidden</b>
|
||||
</td>
|
||||
<td class="text-center"><b>Banned</b>
|
||||
</td>
|
||||
<th class="border-right" data-checkbox>
|
||||
<div class="form-check text-center">
|
||||
<input type="checkbox" class="form-check-input" data-checkbox-all>
|
||||
</div>
|
||||
</th>
|
||||
<th class="sort-col text-center"><b>ID</b></th>
|
||||
<th class="sort-col text-left"><b>Team</b></th>
|
||||
<th class="sort-col text-center"><b>Website</b></th>
|
||||
<th class="sort-col text-center"><b>Country</b></th>
|
||||
<th class="sort-col text-center"><b>Hidden</b></th>
|
||||
<th class="sort-col text-center"><b>Banned</b></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for team in teams %}
|
||||
<tr name="{{ team.id }}" data-href="{{ url_for('admin.teams_detail', team_id=team.id) }}">
|
||||
<td class="team-id" value="{{ team.id }}">{{ team.id }}</td>
|
||||
<td class="border-right" data-checkbox>
|
||||
<div class="form-check text-center">
|
||||
<input type="checkbox" class="form-check-input" value="{{ team.id }}" data-team-id="{{ team.id }}">
|
||||
</div>
|
||||
</td>
|
||||
<td class="team-id text-center value="{{ team.id }}">{{ team.id }}</td>
|
||||
<td class="team-name" value="{{ team.name }}">
|
||||
<a href="{{ url_for('admin.teams_detail', team_id=team.id) }}">
|
||||
{{ team.name | truncate(32) }}
|
||||
@@ -137,3 +160,7 @@
|
||||
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
|
||||
{% block entrypoint %}
|
||||
<script defer src="{{ url_for('views.themes', theme='admin', path='js/pages/teams.js') }}"></script>
|
||||
{% endblock %}
|
||||
@@ -17,6 +17,7 @@
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{% if q and field %}
|
||||
@@ -24,55 +25,74 @@
|
||||
{% endif %}
|
||||
|
||||
<form method="GET" class="form-inline">
|
||||
<div class="form-group col-md-2">
|
||||
<label for="sel1" class="sr-only" >Search Field</label>
|
||||
<select class="form-control custom-select w-100" id="sel1" name="field">
|
||||
<option value="name" {% if field == 'name' %}selected{% endif %}>Name</option>
|
||||
<option value="id" {% if field == 'id' %}selected{% endif %}>ID</option>
|
||||
<option value="email" {% if field == 'email' %}selected{% endif %}>Email</option>
|
||||
<option value="affiliation" {% if field == 'affiliation' %}selected{% endif %}>Affiliation</option>
|
||||
<option value="ip" {% if field == 'ip' %}selected{% endif %}>IP Address</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-md-8">
|
||||
<label for="team-name-search" class="sr-only">Parameter</label>
|
||||
<input type="text" class="form-control w-100" id="team-name-search" name="q" placeholder="Search for matching user" {% if q %}value="{{q}}"{% endif %}>
|
||||
</div>
|
||||
<div class="form-group col-md-2">
|
||||
<label for="team-name-search" class="sr-only">Search</label>
|
||||
<button type="submit" class="btn btn-primary w-100"><i class="fas fa-search" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
<div class="form-group col-md-2">
|
||||
<label for="sel1" class="sr-only" >Search Field</label>
|
||||
<select class="form-control custom-select w-100" id="sel1" name="field">
|
||||
<option value="name" {% if field == 'name' %}selected{% endif %}>Name</option>
|
||||
<option value="id" {% if field == 'id' %}selected{% endif %}>ID</option>
|
||||
<option value="email" {% if field == 'email' %}selected{% endif %}>Email</option>
|
||||
<option value="affiliation" {% if field == 'affiliation' %}selected{% endif %}>Affiliation</option>
|
||||
<option value="ip" {% if field == 'ip' %}selected{% endif %}>IP Address</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-md-8">
|
||||
<label for="team-name-search" class="sr-only">Parameter</label>
|
||||
<input type="text" class="form-control w-100" id="team-name-search" name="q" placeholder="Search for matching user" {% if q %}value="{{q}}"{% endif %}>
|
||||
</div>
|
||||
<div class="form-group col-md-2">
|
||||
<label for="team-name-search" class="sr-only">Search</label>
|
||||
<button type="submit" class="btn btn-primary w-100"><i class="fas fa-search" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
|
||||
<table id="teamsboard" class="table table-striped">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="float-right pb-3">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-outline-secondary" data-toggle="tooltip" title="Edit Users" id="users-edit-button">
|
||||
<i class="btn-fa fas fa-pencil-alt"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-danger" data-toggle="tooltip" title="Delete Users" id="users-delete-button">
|
||||
<i class="btn-fa fas fa-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table id="teamsboard" class="table table-striped border">
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="10px" class="text-center"><b>ID</b>
|
||||
</td>
|
||||
<td class="text-center"><b>User</b>
|
||||
</td>
|
||||
<td class="d-md-table-cell d-lg-table-cell text-center"><b>Email</b>
|
||||
</td>
|
||||
<td class=""><b>Website</b>
|
||||
</td>
|
||||
<td class=""><b>Country</b>
|
||||
</td>
|
||||
<td class="text-center"><b>Admin</b>
|
||||
</td>
|
||||
<td class="text-center"><b>Verified</b>
|
||||
</td>
|
||||
<td class="text-center"><b>Hidden</b>
|
||||
</td>
|
||||
<td class="text-center"><b>Banned</b>
|
||||
</td>
|
||||
<th class="border-right" data-checkbox>
|
||||
<div class="form-check text-center">
|
||||
<input type="checkbox" class="form-check-input" data-checkbox-all>
|
||||
</div>
|
||||
</th>
|
||||
<th class="sort-col text-center"><b>ID</b></td>
|
||||
<th class="sort-col text-center"><b>User</b></th>
|
||||
<th class="d-md-table-cell d-lg-table-cell sort-col text-center"><b>Email</b></th>
|
||||
<th class="sort-col"><b>Website</b></th>
|
||||
<th class="sort-col"><b>Country</b></th>
|
||||
<th class="sort-col text-center"><b>Admin</b></th>
|
||||
<th class="sort-col text-center"><b>Verified</b></th>
|
||||
<th class="sort-col text-center"><b>Hidden</b></th>
|
||||
<th class="sort-col text-center"><b>Banned</b></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr name="{{ user.id }}" data-href="{{ url_for('admin.users_detail', user_id=user.id) }}">
|
||||
<td class="team-id" value="{{ user.id }}">{{ user.id }}</td>
|
||||
<td class="border-right" data-checkbox>
|
||||
<div class="form-check text-center">
|
||||
<input type="checkbox" class="form-check-input" value="{{ user.id }}" data-user-id="{{ user.id }}">
|
||||
</div>
|
||||
</td>
|
||||
<td class="team-id text-center" value="{{ user.id }}">{{ user.id }}</td>
|
||||
<td class="team-name" value="{{ user.name }}">
|
||||
<a href="{{ url_for('admin.users_detail', user_id=user.id) }}">
|
||||
{{ user.name | truncate(32) }}
|
||||
|
||||
@@ -256,3 +256,38 @@ export function copyToClipboard(event, selector) {
|
||||
$(event.target).tooltip("hide");
|
||||
}, 1500);
|
||||
}
|
||||
|
||||
export function makeSortableTables() {
|
||||
$("th.sort-col").append(` <i class="fas fa-sort"></i>`);
|
||||
$("th.sort-col").click(function() {
|
||||
var table = $(this)
|
||||
.parents("table")
|
||||
.eq(0);
|
||||
var rows = table
|
||||
.find("tr:gt(0)")
|
||||
.toArray()
|
||||
.sort(comparer($(this).index()));
|
||||
this.asc = !this.asc;
|
||||
if (!this.asc) {
|
||||
rows = rows.reverse();
|
||||
}
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
table.append(rows[i]);
|
||||
}
|
||||
});
|
||||
function comparer(index) {
|
||||
return function(a, b) {
|
||||
var valA = getCellValue(a, index),
|
||||
valB = getCellValue(b, index);
|
||||
return $.isNumeric(valA) && $.isNumeric(valB)
|
||||
? valA - valB
|
||||
: valA.toString().localeCompare(valB);
|
||||
};
|
||||
}
|
||||
function getCellValue(row, index) {
|
||||
return $(row)
|
||||
.children("td")
|
||||
.eq(index)
|
||||
.text();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
CTFd/themes/core/static/js/pages/main.min.js
vendored
2
CTFd/themes/core/static/js/pages/main.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -36,6 +36,7 @@ const roots = {
|
||||
'js': {
|
||||
'pages/main': 'assets/js/pages/main.js',
|
||||
'pages/challenge': 'assets/js/pages/challenge.js',
|
||||
'pages/challenges': 'assets/js/pages/challenges.js',
|
||||
'pages/configs': 'assets/js/pages/configs.js',
|
||||
'pages/notifications': 'assets/js/pages/notifications.js',
|
||||
'pages/editor': 'assets/js/pages/editor.js',
|
||||
|
||||
Reference in New Issue
Block a user