Implement saving content
This commit is contained in:
parent
c3604f38b2
commit
faea8ccc72
|
@ -168,7 +168,7 @@ class DocumentTab:
|
|||
return tag
|
||||
return None
|
||||
|
||||
def get_tag_value(self, name: str, default: str):
|
||||
def get_tag_value(self, name: str, default: str = None):
|
||||
if tag := self.get_tag(name):
|
||||
return tag.value
|
||||
return default
|
||||
|
@ -200,7 +200,7 @@ class Document:
|
|||
return tag
|
||||
return None
|
||||
|
||||
def get_tag_value(self, name: str, default: str):
|
||||
def get_tag_value(self, name: str, default: str = None):
|
||||
if tag := self.get_tag(name):
|
||||
return tag.value
|
||||
return default
|
||||
|
|
|
@ -16,7 +16,16 @@ from flask import (
|
|||
)
|
||||
|
||||
from redstring.library import generate_index_document, generate_default_document
|
||||
from redstring.parser import load, dump, DocumentTab, DocumentTag, TagOptions, DocumentSubtag
|
||||
from redstring.parser import (
|
||||
Document,
|
||||
DocumentTab,
|
||||
DocumentTag,
|
||||
DocumentSubtag,
|
||||
dump,
|
||||
load,
|
||||
parse_document_from_json,
|
||||
TagOptions,
|
||||
)
|
||||
|
||||
|
||||
CONFIG_ENVVAR = 'REDSTRING_CONFIG'
|
||||
|
@ -57,14 +66,23 @@ def new():
|
|||
|
||||
@app.route('/edit/<document_id>', methods=['GET', 'POST'])
|
||||
def edit(document_id):
|
||||
# Load the document to edit
|
||||
doc_path = safe_join(current_app.config['root'], f'{document_id}.json')
|
||||
|
||||
# Check for content updates
|
||||
if request.method == 'POST':
|
||||
sent_json = request.json
|
||||
new_doc: Document = parse_document_from_json(sent_json)
|
||||
with open(doc_path, 'w') as f:
|
||||
dump(new_doc, f)
|
||||
return {}
|
||||
|
||||
# Load the document to edit
|
||||
if not os.path.isfile(doc_path):
|
||||
return abort(404)
|
||||
with open(doc_path) as f:
|
||||
doc = load(f)
|
||||
doc: Document = load(f)
|
||||
|
||||
# Check for structural change requests
|
||||
# Check for structural updates
|
||||
if add := request.args.get('add'):
|
||||
if add == 'tab':
|
||||
new_tab = DocumentTab('newtab', [])
|
||||
|
|
|
@ -103,6 +103,11 @@
|
|||
}
|
||||
table.page-table a {
|
||||
color: #8af;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
table.page-table .numeric-input {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
/* Edit page styling */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.jinja' %}
|
||||
|
||||
{% set page_title = document.get_tag_value('title', document.get_tag('id').value) -%}
|
||||
{% set page_title = document.get_tag_value('title') or document.get_tag_value('id') -%}
|
||||
{% set page_summary = document.get_tag_value('summary', '') %}
|
||||
|
||||
{% block page_scripts %}
|
||||
|
@ -48,6 +48,85 @@ function addTab() {
|
|||
wrapper.appendChild(newPage);
|
||||
}
|
||||
|
||||
function save() {
|
||||
let tabs = document.querySelectorAll(".tab-page");
|
||||
let doc = [];
|
||||
for (var tabDiv of tabs.values()) {
|
||||
let tabName = tabDiv.querySelector(".edit-tab-name").innerText;
|
||||
let tabPriority = tabDiv.querySelector(".tab-priority").value;
|
||||
let tabHideNames = tabDiv.querySelector(".tab-hidenames").checked;
|
||||
let tabPrivate = tabDiv.querySelector(".tab-private").checked;
|
||||
let tab = {
|
||||
name: tabName,
|
||||
tags: [],
|
||||
options: {
|
||||
priority: parseInt(tabPriority),
|
||||
hide_names: tabHideNames,
|
||||
private: tabPrivate,
|
||||
},
|
||||
};
|
||||
doc.push(tab)
|
||||
|
||||
let tags = tabDiv.querySelectorAll(".edit-tag");
|
||||
let subtags = tabDiv.querySelectorAll(".edit-subtag");
|
||||
for (var tagRow of tags.values()) {
|
||||
let tagRowName = tagRow.querySelector(".edit-tag-name").innerText;
|
||||
let tagRowValue = tagRow.querySelector(".edit-tag-value").innerText;
|
||||
let tag = {
|
||||
name: tagRowName,
|
||||
value: tagRowValue,
|
||||
subtags: [],
|
||||
};
|
||||
if (tagRowName != "id") {
|
||||
let optionsRow = tagRow.nextElementSibling;
|
||||
let tagHyperlink = optionsRow.querySelector(".tag-hyperlink").checked;
|
||||
let tagInterlink = optionsRow.querySelector(".tag-interlink").checked;
|
||||
let tagPrivate = optionsRow.querySelector(".tag-private").checked;
|
||||
tag.options = {
|
||||
hyperlink: tagHyperlink,
|
||||
interlink: tagInterlink,
|
||||
private: tagPrivate,
|
||||
};
|
||||
}
|
||||
tab.tags.push(tag);
|
||||
|
||||
let tagRowId = tagRow.dataset.tag;
|
||||
for (var subtagRow of subtags.values()) {
|
||||
let subtagRowId = subtagRow.dataset.tag;
|
||||
if (subtagRowId == tagRowId) {
|
||||
let subtagRowName = subtagRow.querySelector(".edit-subtag-name").innerText;
|
||||
let subtagRowValue = subtagRow.querySelector(".edit-subtag-value").innerText;
|
||||
let subOptionsRow = subtagRow.nextElementSibling;
|
||||
let subtagHyperlink = subOptionsRow.querySelector(".tag-hyperlink").checked;
|
||||
let subtagInterlink = subOptionsRow.querySelector(".tag-interlink").checked;
|
||||
let subtagPrivate = subOptionsRow.querySelector(".tag-private").checked;
|
||||
let subtag = {
|
||||
name: subtagRowName,
|
||||
value: subtagRowValue,
|
||||
options: {
|
||||
hyperlink: subtagHyperlink,
|
||||
interlink: subtagInterlink,
|
||||
private: subtagPrivate,
|
||||
}
|
||||
};
|
||||
tag.subtags.push(subtag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("POST", "/edit/{{ document.get_tag_value('id') }}", true);
|
||||
req.setRequestHeader("Content-type", "application/json");
|
||||
req.responseType = "json";
|
||||
req.onreadystatechange = function () {
|
||||
if (req.readyState == 4 && req.status == 200) {
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
req.send(JSON.stringify(doc));
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
// Respect fragment as a tab selector shortcut
|
||||
if (window.location.hash) {
|
||||
|
@ -67,21 +146,17 @@ window.onload = function () {
|
|||
|
||||
<tr>
|
||||
<td><i>tab name</i></td>
|
||||
<td><div contenteditable>{{ tab.name }}</div></td>
|
||||
<td><div class="edit-tab-name" contenteditable>{{ tab.name }}</div></td>
|
||||
</tr>
|
||||
|
||||
<tr><td></td>
|
||||
<td><i>priority: <a href="/edit/{{ document.get_tag('id').value }}?tab={{ tab.name }}&option=priority">{{ tab.options.priority }}</a> — hide_names: <a href="/edit/{{ document.get_tag('id').value }}?tab={{ tab.name }}&option=hide_names">{{ tab.options.hide_names|lower }}</a> — private: <a href="/edit/{{ document.get_tag('id').value }}?tab={{ tab.name }}&option=private">{{ tab.options.private|lower }}</a></td>
|
||||
<td><input class="tab-priority numeric-input" type="number" value="{{ tab.options.priority }}"> <i>priority</i> — <input class="tab-hidenames" type="checkbox"{% if tab.options.hide_names %} checked {% endif %}> <i>hide names</i> — <input class="tab-private" type="checkbox"{% if tab.options.private %} checked{% endif %}> <i>private</i></td>
|
||||
</tr>
|
||||
|
||||
{% for tag in tab.tags %}
|
||||
<tr>
|
||||
{%- if tag.name == 'id' -%}
|
||||
<td>{{ tag.name }}</td>
|
||||
{%- else -%}
|
||||
<td><div contenteditable>{{ tag.name }}</div></td>
|
||||
{% endif %}
|
||||
<td><div contenteditable>{{ tag.value }}</div></td>
|
||||
<tr class="edit-tag" data-tag="{{ tag.name }}" >
|
||||
<td><div class="edit-tag-name"{% if tag.name != 'id' %} contenteditable{% endif %}>{{ tag.name }}</div></td>
|
||||
<td><div class="edit-tag-value" contenteditable>{{ tag.value }}</div></td>
|
||||
</tr>
|
||||
|
||||
{%- if tag.name != 'id' -%}
|
||||
|
@ -91,14 +166,14 @@ window.onload = function () {
|
|||
{%- else -%}
|
||||
<a href="/edit/{{ document.get_tag('id').value }}?add=subtag&tag={{ tag.name }}">└ +</a>
|
||||
{%- endif -%}</td>
|
||||
<td><i>hyperlink: <a href="/edit/{{ document.get_tag('id').value }}?tag={{ tag.name }}&option=hyperlink">{{ tag.options.hyperlink|lower }}</a> — interlink: <a href="/edit/{{ document.get_tag('id').value }}?tag={{ tag.name }}&option=interlink">{{ tag.options.interlink|lower }}</a> — private: <a href="/edit/{{ document.get_tag('id').value }}?tag={{ tag.name }}&option=private">{{ tag.options.private|lower }}</a></td>
|
||||
<td><input class="tag-hyperlink" type="checkbox"{% if tag.options.hyperlink %} checked {% endif %}> <i>hyperlink</i> — <input class="tag-interlink" type="checkbox"{% if tag.options.interlink %} checked {% endif %}> <i>interlink</i> — <input class="tag-private" type="checkbox"{% if tag.options.private %} checked {% endif %}> <i>private</i></td>
|
||||
</tr>
|
||||
{%- endif -%}
|
||||
|
||||
{% for subtag in tag.subtags %}
|
||||
<tr>
|
||||
<td><div contenteditable>{{ subtag.name }}</div></td>
|
||||
<td><div contenteditable>{{ subtag.value }}</div></td>
|
||||
<tr class="edit-subtag" data-tag="{{ tag.name }}">
|
||||
<td><div class="edit-subtag-name" contenteditable>{{ subtag.name }}</div></td>
|
||||
<td><div class="edit-subtag-value" contenteditable>{{ subtag.value }}</div></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
@ -109,7 +184,7 @@ window.onload = function () {
|
|||
<a href="/edit/{{ document.get_tag('id').value }}?add=subtag&tag={{ tag.name }}">└ +</a>
|
||||
{%- endif -%}
|
||||
</td>
|
||||
<td></td>
|
||||
<td><input class="tag-hyperlink" type="checkbox"{% if subtag.options.hyperlink %} checked {% endif %}> <i>hyperlink</i> — <input class="tag-interlink" type="checkbox"{% if subtag.options.interlink %} checked {% endif %}> <i>interlink</i> — <input class="tag-private" type="checkbox"{% if subtag.options.private %} checked {% endif %}> <i>private</i></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
|
@ -120,6 +195,11 @@ window.onload = function () {
|
|||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><a onclick="javascript:save()">submit changes</a></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
|
Loading…
Reference in New Issue