Implement saving content

This commit is contained in:
Tim Van Baak 2021-02-17 19:44:52 -08:00
parent c3604f38b2
commit faea8ccc72
4 changed files with 124 additions and 21 deletions

View File

@ -168,7 +168,7 @@ class DocumentTab:
return tag return tag
return None 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): if tag := self.get_tag(name):
return tag.value return tag.value
return default return default
@ -200,7 +200,7 @@ class Document:
return tag return tag
return None 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): if tag := self.get_tag(name):
return tag.value return tag.value
return default return default

View File

@ -16,7 +16,16 @@ from flask import (
) )
from redstring.library import generate_index_document, generate_default_document 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' CONFIG_ENVVAR = 'REDSTRING_CONFIG'
@ -57,14 +66,23 @@ def new():
@app.route('/edit/<document_id>', methods=['GET', 'POST']) @app.route('/edit/<document_id>', methods=['GET', 'POST'])
def edit(document_id): def edit(document_id):
# Load the document to edit
doc_path = safe_join(current_app.config['root'], f'{document_id}.json') 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): if not os.path.isfile(doc_path):
return abort(404) return abort(404)
with open(doc_path) as f: 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 := request.args.get('add'):
if add == 'tab': if add == 'tab':
new_tab = DocumentTab('newtab', []) new_tab = DocumentTab('newtab', [])

View File

@ -103,6 +103,11 @@
} }
table.page-table a { table.page-table a {
color: #8af; color: #8af;
cursor: pointer;
text-decoration: underline;
}
table.page-table .numeric-input {
width: 50px;
} }
/* Edit page styling */ /* Edit page styling */

View File

@ -1,6 +1,6 @@
{% extends 'base.jinja' %} {% 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', '') %} {% set page_summary = document.get_tag_value('summary', '') %}
{% block page_scripts %} {% block page_scripts %}
@ -48,6 +48,85 @@ function addTab() {
wrapper.appendChild(newPage); 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 () { window.onload = function () {
// Respect fragment as a tab selector shortcut // Respect fragment as a tab selector shortcut
if (window.location.hash) { if (window.location.hash) {
@ -67,21 +146,17 @@ window.onload = function () {
<tr> <tr>
<td><i>tab name</i></td> <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>
<tr><td></td> <tr><td></td>
<td><i>priority: <a href="/edit/{{ document.get_tag('id').value }}?tab={{ tab.name }}&option=priority">{{ tab.options.priority }}</a> &mdash; hide_names: <a href="/edit/{{ document.get_tag('id').value }}?tab={{ tab.name }}&option=hide_names">{{ tab.options.hide_names|lower }}</a> &mdash; 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> &mdash; <input class="tab-hidenames" type="checkbox"{% if tab.options.hide_names %} checked {% endif %}> <i>hide names</i> &mdash; <input class="tab-private" type="checkbox"{% if tab.options.private %} checked{% endif %}> <i>private</i></td>
</tr> </tr>
{% for tag in tab.tags %} {% for tag in tab.tags %}
<tr> <tr class="edit-tag" data-tag="{{ tag.name }}" >
{%- if tag.name == 'id' -%} <td><div class="edit-tag-name"{% if tag.name != 'id' %} contenteditable{% endif %}>{{ tag.name }}</div></td>
<td>{{ tag.name }}</td> <td><div class="edit-tag-value" contenteditable>{{ tag.value }}</div></td>
{%- else -%}
<td><div contenteditable>{{ tag.name }}</div></td>
{% endif %}
<td><div contenteditable>{{ tag.value }}</div></td>
</tr> </tr>
{%- if tag.name != 'id' -%} {%- if tag.name != 'id' -%}
@ -91,14 +166,14 @@ window.onload = function () {
{%- else -%} {%- else -%}
<a href="/edit/{{ document.get_tag('id').value }}?add=subtag&tag={{ tag.name }}">&#9492; +</a> <a href="/edit/{{ document.get_tag('id').value }}?add=subtag&tag={{ tag.name }}">&#9492; +</a>
{%- endif -%}</td> {%- endif -%}</td>
<td><i>hyperlink: <a href="/edit/{{ document.get_tag('id').value }}?tag={{ tag.name }}&option=hyperlink">{{ tag.options.hyperlink|lower }}</a> &mdash; interlink: <a href="/edit/{{ document.get_tag('id').value }}?tag={{ tag.name }}&option=interlink">{{ tag.options.interlink|lower }}</a> &mdash; 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> &mdash; <input class="tag-interlink" type="checkbox"{% if tag.options.interlink %} checked {% endif %}> <i>interlink</i> &mdash; <input class="tag-private" type="checkbox"{% if tag.options.private %} checked {% endif %}> <i>private</i></td>
</tr> </tr>
{%- endif -%} {%- endif -%}
{% for subtag in tag.subtags %} {% for subtag in tag.subtags %}
<tr> <tr class="edit-subtag" data-tag="{{ tag.name }}">
<td><div contenteditable>{{ subtag.name }}</div></td> <td><div class="edit-subtag-name" contenteditable>{{ subtag.name }}</div></td>
<td><div contenteditable>{{ subtag.value }}</div></td> <td><div class="edit-subtag-value" contenteditable>{{ subtag.value }}</div></td>
</tr> </tr>
<tr> <tr>
@ -109,7 +184,7 @@ window.onload = function () {
<a href="/edit/{{ document.get_tag('id').value }}?add=subtag&tag={{ tag.name }}">&#9492; +</a> <a href="/edit/{{ document.get_tag('id').value }}?add=subtag&tag={{ tag.name }}">&#9492; +</a>
{%- endif -%} {%- endif -%}
</td> </td>
<td></td> <td><input class="tag-hyperlink" type="checkbox"{% if subtag.options.hyperlink %} checked {% endif %}> <i>hyperlink</i> &mdash; <input class="tag-interlink" type="checkbox"{% if subtag.options.interlink %} checked {% endif %}> <i>interlink</i> &mdash; <input class="tag-private" type="checkbox"{% if subtag.options.private %} checked {% endif %}> <i>private</i></td>
</tr> </tr>
{% endfor %} {% endfor %}
@ -120,6 +195,11 @@ window.onload = function () {
<td></td> <td></td>
</tr> </tr>
<tr>
<td></td>
<td><a onclick="javascript:save()">submit changes</a></td>
</tr>
</table> </table>
</div> </div>
{% endmacro %} {% endmacro %}