Commit 22ec1e70 authored by buttle's avatar buttle

Moved Footnote to Data protection consent

Fixed menu.
parent 6300cd3a
......@@ -31,11 +31,12 @@ babel = Babel(app)
csrf = CSRFProtect()
csrf.init_app(app)
app.config['APP_VERSION'] = 18
app.config['SCHEMA_VERSION'] = 9
app.config['APP_VERSION'] = 19
app.config['SCHEMA_VERSION'] = 10
app.config['RESERVED_SLUGS'] = ['static', 'admin', 'admins', 'user', 'users', 'form', 'forms', 'site', 'sites']
app.config['RESERVED_FORM_ELEMENT_NAMES'] = ['created', 'csrf_token']
# DPL = Data Protection Law
app.config['RESERVED_FORM_ELEMENT_NAMES'] = ['created', 'csrf_token', 'DPL']
app.config['RESERVED_USERNAMES'] = ['system', 'admin']
app.config['BABEL_TRANSLATION_DIRECTORIES'] = 'translations;form_templates/translations'
......
......@@ -117,6 +117,18 @@ def migrateMongoSchema(schemaVersion):
schemaVersion=9
if schemaVersion < 10:
# Changed site footnote to personalDataConsent.
for site in mongo.db.sites.find():
consent=site["defaultFormFootNote"]
mongo.db.sites.update_one({"_id": site["_id"]}, {"$unset": {'defaultFormFootNote' :1}, "$set": {"personalDataConsent": consent} })
for form in mongo.db.forms.find():
boolean=form["showFootNote"]
mongo.db.forms.update_one({"_id": form["_id"]}, {"$unset": {'showFootNote' :1}, "$set": {"requireDataConsent": boolean }})
schemaVersion=10
# this can't be a good migration setup :(
return schemaVersion
......@@ -364,6 +364,20 @@ class Form(object):
def fieldIndex(self):
return self.form['fieldIndex']
def getFieldIndexForDataDisplay(self):
"""
formbuilder adds HTML tags to labels like '<br>' or '<div></div>'.
The tags (formatted lables) are good when rendering the form but we do not want them included in CSV column headers.
This function is called when viewing form entry data.
"""
result=[]
for field in self.fieldIndex:
result.append({'label': stripHTMLTagsForLabel(field['label']), 'name': field['name']})
""" insert this optional field """
if self.isDataConsentEnabled():
result.insert(1, {"name": "DPL", "label": gettext("DPL")})
return result
@property
def entries(self):
return self.form['entries']
......@@ -409,15 +423,15 @@ class Form(object):
def url(self):
return "%s%s" % (self.site.host_url, self.slug)
def isFootNoteEnabled(self):
if not self.site.isDefaultFootNoteEnabled():
def isDataConsentEnabled(self):
if not self.site.isPersonalDataConsentEnabled():
return False
else:
return self.form["showFootNote"]
return self.form["requireDataConsent"]
@property
def footNote(self):
return self.site.data['defaultFormFootNote']['html']
def dataConsent(self):
return self.site.data['personalDataConsent']['html']
@property
def lastEntryDate(self):
......@@ -578,10 +592,10 @@ class Form(object):
return self.editors[editor_id]['notification']['expiredForm']
return False
def toggleShowFootNote(self):
self.form['showFootNote'] = False if self.form['showFootNote'] else True
def toggleRequireDataConsent(self):
self.form['requireDataConsent'] = False if self.form['requireDataConsent'] else True
mongo.db.forms.save(self.form)
return self.form['showFootNote']
return self.form['requireDataConsent']
def addLog(self, message, anonymous=False):
if anonymous:
......@@ -630,7 +644,7 @@ class Site(object):
"invitationOnly": True,
"siteName": "gng-forms!",
"noreplyEmailAddress": "[email protected]%s" % hostname,
"defaultFormFootNote": {"markdown": "", "html": "", "enabled": False }
"personalDataConsent": {"markdown": "", "html": "", "enabled": False }
}
mongo.db.sites.insert_one(newSiteData)
#create the Installation if it doesn't exist
......@@ -671,14 +685,14 @@ class Site(object):
mongo.db.sites.save(self.site)
def saveDefaultFormFootNote(self, MDtext):
self.site['defaultFormFootNote'] = { 'markdown':escapeMarkdown(MDtext),
self.site['personalDataConsent'] = { 'markdown':escapeMarkdown(MDtext),
'html':markdown2HTML(MDtext),
'enabled': self.site['defaultFormFootNote']['enabled']}
'enabled': self.site['personalDataConsent']['enabled']}
mongo.db.sites.save(self.site)
@property
def defaultFormFootNote(self):
return self.site['defaultFormFootNote']
def personalDataConsent(self):
return self.site['personalDataConsent']
@property
def noreplyEmailAddress(self):
......@@ -693,8 +707,8 @@ class Site(object):
def invitationOnly(self):
return self.site['invitationOnly']
def isDefaultFootNoteEnabled(self):
return self.site["defaultFormFootNote"]["enabled"]
def isPersonalDataConsentEnabled(self):
return self.site["personalDataConsent"]["enabled"]
@property
def totalUsers(self):
......@@ -709,10 +723,10 @@ class Site(object):
mongo.db.sites.save(self.site)
return self.site["invitationOnly"]
def toggleDefaultFootNoteEnabled(self):
self.site["defaultFormFootNote"]["enabled"] = False if self.site["defaultFormFootNote"]["enabled"] else True
def togglePersonalDataConsentEnabled(self):
self.site["personalDataConsent"]["enabled"] = False if self.site["personalDataConsent"]["enabled"] else True
mongo.db.sites.save(self.site)
return self.site["defaultFormFootNote"]["enabled"]
return self.site["personalDataConsent"]["enabled"]
def toggleScheme(self):
self.site["scheme"] = 'https' if self.site["scheme"]=='http' else 'http'
......
......@@ -23,7 +23,7 @@ hr { margin-top: 5px }
font-style: italic;
}
.formFootNote { padding: 1em 0 1em 0 }
.formDataConsent { padding: 1em 0 2em 0 }
/* ######### Flash messages ######### */
.success {
......@@ -73,6 +73,7 @@ hr { margin-top: 5px }
}
.deleted-row {
background-color: #FAAFBE;
text-decoration: line-through;
}
/* ######### formBuilder fixes ######### */
input[type="date"], input[type="number"] {
......
......@@ -36,7 +36,7 @@
<a href="/forms">{%trans%}My forms{%endtrans%}</a> |
{% endif %}
<a href="/user/{{ session['username'] }}">{%trans%}Settings{%endtrans%}</a> |
<a href="/user/{{ g.current_user.username }}">{%trans%}Settings{%endtrans%}</a> |
<a href="/site/logout">{%trans%}Logout{%endtrans%}</a>
</div>
</div>
......
......@@ -11,11 +11,14 @@
<hr />
<div id="fb-render"></div>
<input class="btn-success btn" type="submit" value="{%trans%}Send{%endtrans%}" disabled />
<div id="footnote" class="formFootNote" {% if not form.isFootNoteEnabled() %}style="display:none;"{% endif %}>
{{ form.footNote|safe }}
<div id="dataConsent" class="formDataConsent" {% if not form.isDataConsentEnabled() %}style="display:none;"{% endif %}>
{{ form.dataConsent|safe }}
{%trans%}I agree{%endtrans%}
<input type="checkbox" style="position:relative; top:3px;" required />
</div>
<input class="btn-success btn" type="submit" value="{%trans%}Send{%endtrans%}" disabled />
<p>&nbsp;</p>
<div style="font-size:1.4em">
......@@ -134,17 +137,17 @@
</td>
</tr>
{% if form.site.isDefaultFootNoteEnabled() %}
{% if form.site.isPersonalDataConsentEnabled() %}
<tr>
<td>{%trans%}Show footnote{%endtrans%}</td>
<td>{%trans%}Require consent{%endtrans%}</td>
<td>
{% if form.editors[g.current_user._id|string] is defined %}
<div id="toggle_footnote" class="btn-group btn-toggle">
<button id="footnote_true" class="btn btn-xs btn-default {% if form.isFootNoteEnabled() %}btn-success{% endif %}">{%trans%}True{%endtrans%}</button>
<button id="footnote_false" class="btn btn-xs btn-default {% if not form.isFootNoteEnabled() %}btn-primary{% endif %}">{%trans%}False{%endtrans%}</button>
<div id="toggle_dataConsent" class="btn-group btn-toggle">
<button id="dataConsent_true" class="btn btn-xs btn-default {% if form.isDataConsentEnabled() %}btn-success{% endif %}">{%trans%}True{%endtrans%}</button>
<button id="dataConsent_false" class="btn btn-xs btn-default {% if not form.isDataConsentEnabled() %}btn-primary{% endif %}">{%trans%}False{%endtrans%}</button>
</div>
{% else %}
{{ form.isFootNoteEnabled() }}
{{ form.isDataConsentEnabled() }}
{% endif %}
</td>
</tr>
......@@ -212,9 +215,9 @@ document.getElementById('toggle_enabled').addEventListener('click', function(evt
}
});
});
document.getElementById('toggle_footnote').addEventListener('click', function(evt){
document.getElementById('toggle_dataConsent').addEventListener('click', function(evt){
$.ajax({
url : "/form/toggle-footnote/{{ form._id }}",
url : "/form/toggle-data-consent/{{ form._id }}",
type: "POST",
dataType: "json",
beforeSend: function(xhr, settings) {
......@@ -224,15 +227,15 @@ document.getElementById('toggle_footnote').addEventListener('click', function(ev
},
success: function(data, textStatus, jqXHR)
{
if (data.footnote == true) {
$('#footnote_true').addClass('btn-success');
$('#footnote_false').removeClass('btn-primary');
$('#footnote').show();
if (data.consent == true) {
$('#dataConsent_true').addClass('btn-success');
$('#dataConsent_false').removeClass('btn-primary');
$('#dataConsent').show();
}
else if (data.footnote == false) {
$('#footnote_true').removeClass('btn-success');
$('#footnote_false').addClass('btn-primary');
$('#footnote').hide();
else if (data.consent == false) {
$('#dataConsent_true').removeClass('btn-success');
$('#dataConsent_false').addClass('btn-primary');
$('#dataConsent').hide();
}
}
});
......
......@@ -50,10 +50,10 @@
<!-- Keep the data TD on one line! -->
{% for entry in form.entries %}
<tr>
<td id="row_{{ loop.index }}" style="border-right: 1px solid #ccc; border-left: 1px solid #ccc;">
<td style="border-right: 1px solid #ccc; border-left: 1px solid #ccc;">
<i class="fa fa-ban delete-row" aria-hidden="true"></i>
</td>
{% for field in fieldIndex %}
{% for field in fieldIndex %}
<td style="border-right: 1px solid #ccc;">{{ entry[field['name']] }}</td>
{% endfor %}
</tr>
......@@ -61,11 +61,28 @@
</table>
</div>
{% if form.editors[g.current_user._id|string] is defined %}
<script>
var csrftoken = "{{ csrf_token() }}";
var deletedEntries={};
var fieldIndex={{fieldIndex|tojson}};
function getFieldValueInRow(fieldName, $row){
var arrayLength = fieldIndex.length;
for (var loop = 0; loop < arrayLength; loop++) {
if (fieldIndex[loop]["name"] == fieldName) {
return $row.children('td').eq(loop+1).html()
}
}
return null;
}
function getRowData($row) {
var rowData = new Array();
var arrayLength = fieldIndex.length;
for (var loop = 0; loop < arrayLength; loop++) {
rowData.push({"name": fieldIndex[loop]["name"], "value": $row.children('td').eq(loop+1).html()})
}
return rowData;
}
$(document).ready(function() {
$('#formEntries').DataTable({
"language": {
......@@ -76,78 +93,51 @@ $(document).ready(function() {
{ "orderable": false, "targets": 0 }
]
});
$('#formEntries tbody').on('click', '.delete-row', function () {
var $row=$(this).parents('tr');
var $row_number=$(this).parent('td').attr('id');
var rowData = new Array();
$row.find('td:not(:first-child)').each (function() {
rowData.push($(this).html())
});
//console.log(rowData);
$.ajax({
url : "/forms/delete-entry/{{ form._id }}",
type: "POST",
dataType: "json",
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify(rowData),
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
},
success: function(data, textStatus, jqXHR)
{
if (data.deleted == true) {
deletedEntries[$row_number] = rowData;
//console.log(deletedEntries);
$row.children(':not(:first-child)').addClass('deleted-row');
$row.children(':not(:first-child)').html('');
$row.children('td').eq(1).html("{%trans%}Deleted{%endtrans%}");
$row.children('td').eq(0).html('<i class="fa fa-undo undo-delete-row" aria-hidden="true"></i>');
}
$('.delete-row').attr('title', "{%trans%}Delete entry{%endtrans%}");
});
$('#formEntries tbody').on('click', '.delete-row', function () {
var $row=$(this).parents('tr');
$.ajax({
url : "/forms/delete-entry/{{ form._id }}",
type: "POST",
dataType: "json",
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify({"created": getFieldValueInRow("created", $row)}),
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
},
success: function(data, textStatus, jqXHR)
{
if (data.deleted == true) {
$row.children(':not(:first-child)').addClass('deleted-row');
$row.children('td').eq(0).html('<i class="fa fa-undo undo-delete-row" aria-hidden="true"></i>');
}
});
});
$('#formEntries tbody').on('click', '.undo-delete-row', function () {
var $row_number=$(this).parent('td').attr('id');
//console.log($(this).parents('td').attr('id'));
if (!($row_number in deletedEntries)) {
return;
}
var rowData = deletedEntries[$row_number]
var $row = $(this).parents('tr');
$.ajax({
url : "/forms/undo-delete-entry/{{ form._id }}",
type: "POST",
dataType: "json",
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify(rowData),
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
},
success: function(data, textStatus, jqXHR)
{
if (data.undone == true) {
delete deletedEntries[$row_number]
//console.log(deletedEntries);
//console.log(rowData);
loop=0
$row.find('td:not(:first-child)').each (function() {
$(this).html(rowData[loop])
loop=loop+1;
});
$row.children(':not(:first-child)').removeClass('deleted-row');
$row.children('td').eq(0).html('<i class="fa fa-ban delete-row" aria-hidden="true"></i>');
}
});
});
$('#formEntries tbody').on('click', '.undo-delete-row', function () {
var $row = $(this).parents('tr');
$.ajax({
url : "/forms/undo-delete-entry/{{ form._id }}",
type: "POST",
dataType: "json",
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify(getRowData($row)),
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
},
success: function(data, textStatus, jqXHR)
{
if (data.undone == true) {
$row.children(':not(:first-child)').removeClass('deleted-row');
$row.children('td').eq(0).html('<i class="fa fa-ban delete-row" aria-hidden="true"></i>');
}
});
}
});
$('.delete-row').attr('title', "{%trans%}Delete entry{%endtrans%}");
});
document.getElementById('toggle_notification').addEventListener('click', function(evt){
$.ajax({
......
......@@ -177,14 +177,14 @@
</td>
</tr>
<tr>
<td>{%trans%}Form foot note{%endtrans%}</td>
<td>{%trans%}Data protection consent{%endtrans%}</td>
<td>
<a id="show-editor" style="cursor:pointer">{%trans%}Edit text{%endtrans%}</a>
</td>
<td class="text-right">
<div id="toggle_footnote_enabled" class="btn-group btn-toggle">
<button id="footnote_enabled_true" class="btn btn-xs btn-default {% if site.isDefaultFootNoteEnabled() %}btn-success{% endif %}">{%trans%}Enabled{%endtrans%}</button>
<button id="footnote_enabled_false" class="btn btn-xs btn-default {% if not site.isDefaultFootNoteEnabled() %}btn-primary{% endif %}">{%trans%}Disabled{%endtrans%}</button>
<div id="toggle_dataprotection_enabled" class="btn-group btn-toggle">
<button id="dataprotection_enabled_true" class="btn btn-xs btn-default {% if site.isPersonalDataConsentEnabled() %}btn-success{% endif %}">{%trans%}Enabled{%endtrans%}</button>
<button id="dataprotection_enabled_false" class="btn btn-xs btn-default {% if not site.isPersonalDataConsentEnabled() %}btn-primary{% endif %}">{%trans%}Disabled{%endtrans%}</button>
</div>
</div>
</td>
......@@ -197,7 +197,7 @@
<p></p>
<form id="editor-form" action="/site/save-default-footnote" method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<textarea id="sm-editor" name="editor">{{ site.defaultFormFootNote['markdown'] }}</textarea>
<textarea id="sm-editor" name="editor">{{ site.personalDataConsent['markdown'] }}</textarea>
</form>
</div>
......@@ -349,9 +349,9 @@ document.getElementById('toggle_invitation_only').addEventListener('click', func
});
});
document.getElementById('toggle_footnote_enabled').addEventListener('click', function(evt){
document.getElementById('toggle_dataprotection_enabled').addEventListener('click', function(evt){
$.ajax({
url : "/admin/toggle-default-footnote",
url : "/admin/toggle-dataprotection",
type: "POST",
dataType: "json",
beforeSend: function(xhr, settings) {
......@@ -361,13 +361,13 @@ document.getElementById('toggle_footnote_enabled').addEventListener('click', fun
},
success: function(data, textStatus, jqXHR)
{
if (data.footnote_enabled == true) {
$('#footnote_enabled_true').addClass('btn-success');
$('#footnote_enabled_false').removeClass('btn-primary');
if (data.dataprotection_enabled == true) {
$('#dataprotection_enabled_true').addClass('btn-success');
$('#dataprotection_enabled_false').removeClass('btn-primary');
}
else if (data.footnote_enabled == false) {
$('#footnote_enabled_true').removeClass('btn-success');
$('#footnote_enabled_false').addClass('btn-primary');
else if (data.dataprotection_enabled == false) {
$('#dataprotection_enabled_true').removeClass('btn-success');
$('#dataprotection_enabled_false').addClass('btn-primary');
}
}
});
......
......@@ -9,11 +9,15 @@
<form method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<div id="fb-render"></div>
{% if form.isDataConsentEnabled() %}
<div class="formDataConsent">
{{ form.dataConsent|safe }}
{%trans%}I agree{%endtrans%}
<input type="checkbox" style="position:relative; top:3px;" name="DPL" value="ok" required />
</div>
{% endif %}
<input class="btn-success btn" type="submit" value="{%trans%}Send{%endtrans%}">
</form>
{% if form.isFootNoteEnabled() %}
<div class="formFootNote">{{ form.footNote|safe }}</div>
{% endif %}
</div>
<div class="row col-md-3"></div>
</div>
......
......@@ -200,19 +200,6 @@ def getFieldByNameInIndex(index, name):
return None
def removeHTMLFromLabels(fieldIndex):
"""
formbuilder adds HTML tags to labels like '<br>' or '<div></div>'.
The tags (formatted lables) are good when rendering the form but we do not want them included in CSV column headers.
This function is called when viewing form entry data.
"""
result=[]
for field in fieldIndex:
result.append({'label': stripHTMLTagsForLabel(field['label']), 'name': field['name']})
return result
""" ######## Tokens ######## """
def getRandomString(length=32):
......
......@@ -163,9 +163,8 @@ def view_entries(slug, key):
if not queriedForm or not queriedForm.areEntriesShared():
return render_template('page-not-found.html'), 400
fieldIndex=removeHTMLFromLabels(queriedForm.fieldIndex)
return render_template('view-results.html', form=queriedForm,
fieldIndex=fieldIndex,
fieldIndex=queriedForm.getFieldIndexForDataDisplay(),
language=get_locale())
......@@ -494,6 +493,7 @@ def save_form(_id=None):
queriedForm.data["structure"]=session["formStructure"]
queriedForm.data["fieldIndex"]=session["formFieldIndex"]
queriedForm.data["afterSubmitText"]=afterSubmitText
queriedForm.save()
......@@ -508,6 +508,7 @@ def save_form(_id=None):
if Form(slug=session['slug'], hostname=Site().hostname):
flash(gettext("Slug is not unique. %s" % session['slug']), 'error')
return redirect(make_url_for('edit_form'))
newFormData={
"created": datetime.date.today().strftime("%Y-%m-%d"),
"author": str(g.current_user._id),
......@@ -527,7 +528,7 @@ def save_form(_id=None):
"expireDate": None},
"afterSubmitText": afterSubmitText,
"log": [],
"showFootNote": False
"requireDataConsent": Site().isPersonalDataConsentEnabled()
}
newForm=Form().insert(newFormData)
clearSessionFormData()
......@@ -601,15 +602,15 @@ def toggle_form_notification(_id):
return JsonResponse(json.dumps())
return JsonResponse(json.dumps({'notification':form.toggleNotification()}))
@app.route('/form/toggle-footnote/<string:_id>', methods=['POST'])
@app.route('/form/toggle-data-consent/<string:_id>', methods=['POST'])
@enabled_user_required
def toggle_form_footnote(_id):
form=Form(_id=_id, editor=str(g.current_user._id))
if not form:
def toggle_form_dataconsent(_id):
queriedForm=Form(_id=_id, editor=str(g.current_user._id))
if not queriedForm:
return JsonResponse(json.dumps())
footnoteBool=form.toggleShowFootNote()
form.addLog(gettext("Footnote enabled set to: %s" % footnoteBool))
return JsonResponse(json.dumps({'footnote':footnoteBool}))
dataConsentBool=queriedForm.toggleRequireDataConsent()
queriedForm.addLog(gettext("Data protection consent set to: %s" % dataConsentBool))
return JsonResponse(json.dumps({'consent':dataConsentBool}))
@app.route('/form/toggle-expiration-notification/<string:_id>', methods=['POST'])
@enabled_user_required
......@@ -630,9 +631,8 @@ def list_entries(_id):
flash(gettext("No form found"), 'warning')
return redirect(make_url_for('my_forms'))
fieldIndex=removeHTMLFromLabels(queriedForm.fieldIndex)
return render_template('list-entries.html', form=queriedForm,
fieldIndex=fieldIndex)
fieldIndex=queriedForm.getFieldIndexForDataDisplay())
@app.route('/forms/csv/<string:_id>', methods=['GET'])
......@@ -659,16 +659,17 @@ def delete_entry(_id):
if not queriedForm:
return json.dumps({'deleted': False})
foundEntries = [entry for entry in queriedForm.entries if entry['created'] == request.json[0]]
# we going to use the entry's "created" value as a unique value (gulps).
if not "created" in request.json:
return json.dumps({'deleted': False})
foundEntries = [entry for entry in queriedForm.entries if entry['created'] == request.json["created"]]
if not foundEntries or len(foundEntries) > 1:
""" If there are two entries with the same 'created' value, we don't delete anything """
return json.dumps({'deleted': False})
queriedForm.entries.remove(foundEntries[0])
if not queriedForm.hasExpired() and queriedForm.expired:
queriedForm.expired=False
queriedForm.entries.remove(foundEntries[0])
queriedForm.expired = queriedForm.hasExpired()
queriedForm.save()
queriedForm.addLog(gettext("Deleted an entry"))
return json.dumps({'deleted': True})
......@@ -680,18 +681,24 @@ def undo_delete_entry(_id):
if not queriedForm:
return json.dumps({'undone': False})
foundEntries = [entry for entry in queriedForm.entries if entry['created'] == request.json[0]]
# check we have a "created" key
created_pos=next((i for i,field in enumerate(request.json) if "name" in field and field["name"] == "created"), None)
if not isinstance(created_pos, int):
return json.dumps({'undone': False})
foundEntries = [entry for entry in queriedForm.entries if entry['created'] == request.json[created_pos]["value"]]
if foundEntries:
""" There is already an entry in the DB with the same 'created' value, we don't do anything """
return json.dumps({'undone': False})
entry={}
for loop, field in enumerate(queriedForm.fieldIndex):
for field in request.json:
try:
entry[field['name']]=request.json[loop]
entry[field["name"]]=field["value"]
except:
break
return json.dumps({'undone': False})
queriedForm.entries.append(entry)
queriedForm.expired = queriedForm.hasExpired()
queriedForm.save()
queriedForm.addLog(gettext("Undeleted and entry"))
return json.dumps({'undone': True})
......@@ -1147,10 +1154,10 @@ def toggle_invitation_only(hostname=None):
else:
return json.dumps({'invite': Site().toggleInvitationOnly()})
@app.route('/admin/toggle-default-footnote', methods=['POST'])
@app.route('/admin/toggle-dataprotection', methods=['POST'])
@admin_required
def toggle_default_footnote():
return json.dumps({'footnote_enabled': Site().toggleDefaultFootNoteEnabled()})
def toggle_site_data_consent():
return json.dumps({'dataprotection_enabled': Site().togglePersonalDataConsentEnabled()})
""" Invitations """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment