mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 14:04:20 +01:00
Add basic interface for interacting with field entries
This commit is contained in:
102
CTFd/themes/admin/assets/js/components/configs/fields/Field.vue
Normal file
102
CTFd/themes/admin/assets/js/components/configs/fields/Field.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="border-bottom">
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
class="close float-right"
|
||||
aria-label="Close"
|
||||
@click="deleteField()"
|
||||
>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<label>Field Type</label>
|
||||
<select class="form-control custom-select">
|
||||
<option>Text Field</option>
|
||||
<option>Checkbox</option>
|
||||
</select>
|
||||
<small class="form-text text-muted">Type of field shown to the user</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<div class="form-group">
|
||||
<label>Field Name</label>
|
||||
<input type="text" class="form-control" v-model.lazy="field.name">
|
||||
<small class="form-text text-muted">Field name</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<label>Field Description</label>
|
||||
<input type="text" class="form-control" v-model.lazy="field.description">
|
||||
<small id="emailHelp" class="form-text text-muted">Field Description</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input class="form-check-input" type="checkbox" v-model.lazy="field.editable"> Editable by user in profile
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input class="form-check-input" type="checkbox" v-model.lazy="field.required"> Required on registration
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input class="form-check-input" type="checkbox" v-model.lazy="field.public"> Shown on public profile
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row pb-3">
|
||||
<div class="col-md-12">
|
||||
<div class="d-block">
|
||||
<button
|
||||
class="btn btn-sm btn-success btn-outlined float-right"
|
||||
type="button"
|
||||
@click="saveField()"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
index: Number,
|
||||
initialField: Object
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
field: this.initialField
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
saveField: function(){
|
||||
console.log(this.field)
|
||||
// Update field in API
|
||||
},
|
||||
deleteField: function() {
|
||||
// Delete field in API
|
||||
this.$emit('delete-field', this.index);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- You can't use index as :key here b/c Vue is crazy -->
|
||||
<!-- https://rimdev.io/the-v-for-key/ -->
|
||||
<div class="mb-5" v-for="(field, index) in fields" :key="field.id">
|
||||
<Field
|
||||
:index="index"
|
||||
:initialField.sync="fields[index]"
|
||||
@delete-field="deleteField"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="btn btn-sm btn-success btn-outlined float-right"
|
||||
type="button"
|
||||
@click="addField()"
|
||||
>
|
||||
Add New Field
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Field from "./Field.vue";
|
||||
|
||||
export default {
|
||||
name: "FieldList",
|
||||
components: {
|
||||
Field
|
||||
},
|
||||
props: {},
|
||||
data: function() {
|
||||
return {
|
||||
fields: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
addField: function() {
|
||||
this.fields.push({
|
||||
id: `#${Math.random().toString(16).slice(2)}`,
|
||||
name: "",
|
||||
description: "",
|
||||
editable: false,
|
||||
required: false,
|
||||
public: false
|
||||
})
|
||||
console.log(this.$data.fields)
|
||||
},
|
||||
deleteField: function(index) {
|
||||
// if (fieldId) {
|
||||
// Wait for API implementation
|
||||
// }
|
||||
// Remove field at index
|
||||
this.fields.splice(index, 1);
|
||||
console.log(this.fields)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fields.push({
|
||||
id: 1,
|
||||
name: "Name",
|
||||
description: "Desc",
|
||||
editable: true,
|
||||
required: false,
|
||||
public: true
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -9,6 +9,9 @@ import $ from "jquery";
|
||||
import { ezQuery, ezProgressBar, ezAlert } from "core/ezq";
|
||||
import CodeMirror from "codemirror";
|
||||
import "codemirror/mode/htmlmixed/htmlmixed.js";
|
||||
import Vue from "vue/dist/vue.esm.browser";
|
||||
import Field from "../components/configs/fields/Field.vue";
|
||||
import FieldList from "../components/configs/fields/FieldList.vue";
|
||||
|
||||
function loadTimestamp(place, timestamp) {
|
||||
if (typeof timestamp == "string") {
|
||||
@@ -360,4 +363,10 @@ $(() => {
|
||||
$("#mail_username_password").toggle(this.checked);
|
||||
})
|
||||
.change();
|
||||
|
||||
// Insert CommentBox element
|
||||
const fieldList = Vue.extend(FieldList);
|
||||
let vueContainer = document.createElement("div");
|
||||
document.querySelector("#user-field-list").appendChild(vueContainer);
|
||||
new fieldList({}).$mount(vueContainer);
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -23,6 +23,9 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link rounded-0" href="#accounts" role="tab" data-toggle="tab">Accounts</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link rounded-0" href="#fields" role="tab" data-toggle="tab">Custom Fields</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link rounded-0" href="#mlc" role="tab" data-toggle="tab">MajorLeagueCyber</a>
|
||||
</li>
|
||||
@@ -61,6 +64,8 @@
|
||||
|
||||
{% include "admin/configs/accounts.html" %}
|
||||
|
||||
{% include "admin/configs/fields.html" %}
|
||||
|
||||
{% include "admin/configs/mlc.html" %}
|
||||
|
||||
{% include "admin/configs/settings.html" %}
|
||||
|
||||
24
CTFd/themes/admin/templates/configs/fields.html
Normal file
24
CTFd/themes/admin/templates/configs/fields.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<div role="tabpanel" class="tab-pane config-section" id="fields">
|
||||
<form method="POST" autocomplete="off" class="w-100">
|
||||
<h5>Custom Fields</h5>
|
||||
|
||||
<small class="form-text text-muted">
|
||||
Add custom fields to get additional data from your participants
|
||||
</small>
|
||||
|
||||
<ul class="nav nav-tabs mt-3" role="tablist">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link active" href="#user-fields" role="tab" data-toggle="tab">
|
||||
Users
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="user-fields">
|
||||
<div id="user-field-list" class="pt-3">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
Reference in New Issue
Block a user