working UI

This commit is contained in:
evilchili 2025-10-17 19:33:29 -07:00
parent c1272788f0
commit 83527b85f4
12 changed files with 42664 additions and 75 deletions

View File

@ -16,8 +16,10 @@
{% block nav %}
{% include "nav.html" %}
{% include "breadcrumbs.html" %}
{% endblock %}
<div class='table-wrapper'>
<div class='main-aligned'>
<div class='table-wrapper'>
<main>
{% for message in g.messages %}
<div class="alert">
@ -26,6 +28,7 @@
{% endfor %}
{% block content %}{% endblock %}
</main>
</div>
</div>
<footer>
{% block footer %}

View File

@ -1,7 +1,3 @@
<div id='breadcrumbs'>
<div id='breadcrumbs' class='main-aligned'>
<a href="{{ url_for('index') }}">Home</a>{% for (uri, name) in breadcrumbs %}.<a href="{{ uri }}">{{ name }}</a>{% endfor %}
<div id='actions'>
<a id='action__edit' data-state='view'>edit</a>
<a id='action__save' style='display: none;'>save</a>
</div>
</div>

View File

@ -1,5 +1,5 @@
<nav>
<ul class="container">
<ul class="container main-aligned">
<li><a href='{{ root.uri }}'>Home</a></li>
{% for subpage in root.members %}
{% if user.can_read(subpage) %}

View File

@ -1,60 +1,19 @@
{% extends "base.html" %}
{% block styles %}
<link rel="stylesheet" href="https://uicdn.toast.com/editor/latest/toastui-editor.min.css" />
<link rel="stylesheet" href="/static/toastui-editor.css" />
{% endblock %}
{% block content %}
{% include "breadcrumbs.html" %}
<div id='viewer'></div>
<div id='editor'></div>
<div id='editor' class='read-only'></div>
{% endblock %}
{% block scripts %}
<script src="https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js"></script>
<script>
const viewerEl = document.querySelector("#viewer");
const editorEl = document.querySelector("#editor");;
const initialValue = (
"# " + document.getElementById("data_form__title").value +
"\n" +
document.getElementById("data_form__body").value
);
const editor = new toastui.Editor({
el: editorEl,
initialEditType: 'wysiwyg',
initialValue: initialValue,
minHeight: '500px',
previewStyle: 'tab',
usageStatistics: false
});
const edit_btn = document.querySelector("#action__edit");
const save_btn = document.querySelector("#action__save");
toggleEditor = function() {
if (edit_btn.dataset.state == 'view') {
edit_btn.dataset.state = 'edit';
edit_btn.innerText = "discard draft";
viewerEl.style['display'] = "none";
editorEl.style['display'] = "inline";
save_btn.style['display'] = 'inline-block';
} else {
edit_btn.dataset.state = 'view';
edit_btn.innerText = "edit";
editorEl.style['display'] = "none";
viewerEl.style['display'] = "inline";
save_btn.style['display'] = 'none';
}
};
edit_btn.addEventListener('click', toggleEditor)
viewerEl.innerHTML = editor.getHTML();
</script>
<script src="/static/toastui-editor-all.js"></script>
<script src="/static/site.js"></script>
<script>
initialize();
</script>
{% endblock %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -14,7 +14,7 @@ body {
margin: 0px;
box-sizing: border-box;
overflow-wrap: break-word;
overflow-y: scroll;
overflow-y: auto;
scrollbar-gutter: stable;
}
@ -124,6 +124,10 @@ nav > ul > li {
position: relative;
}
nav > ul > li:first-child {
padding-left: 0px;
}
nav > ul > li > a {
color: #fff;
display: inline-block;
@ -174,10 +178,12 @@ nav > ul > li:hover > a {
opacity: 1;
}
#breadcrumbs {
height: var(--breadcrumbs-height);
border-bottom: 1px dotted #DEDEDE;
display: block;
align-content: center;
height: 46px;
line-height: 46px;
width: 100%;
}
#data_form {
@ -185,13 +191,22 @@ nav > ul > li:hover > a {
}
#editor {
display: none;
}
#viewer {
display: inline;
}
.toastui-editor-defaultUI-toolbar {
padding: 0px !important;
margin: 0px !important;
border: 0px !important;
background: transparent !important;
}
.toastui-editor-toolbar {
box-shadow: 0px 3px 5px #CCC;
margin-bottom: 20px !important;
}
/*
#actions {
display: flex;
float: right;
@ -212,15 +227,20 @@ nav > ul > li:hover > a {
color: white;
background: blue;
}
*/
.main-aligned {
display: block;
margin: auto;
max-width: var(--max-width);
min-width: var(--min-width);
}
.table-wrapper {
padding: 0px;
padding-top: var(--wrapper-padding);
position: relative;
display: table;
margin: auto;
width: var(--max-width);
max-width: 960px;
width: 100%;
}
main {
@ -256,6 +276,75 @@ footer {
font-family: var(--default-font-family) !important;
}
#editor .toastui-editor-md-container > div > div,
#editor .toastui-editor-ww-container > div > div {
border: 1px dotted #ccc;
}
#editor .toastui-editor-defaultUI-toolbar {
margin-bottom: 20px;
}
#editor .toastui-editor-toolbar {
position: sticky !important;
top: 0 !important;
z-index: 99 !important;
width: 100% !important;
background: #FFF !important;
}
/* applied to #editor */
.read-only {
}
#editor.read-only .toastui-editor-toolbar {
box-shadow: none;
}
#editor.read-only .toastui-editor-ww-container > div > div {
background: #FFF;
}
div.toastui-editor-md-splitter,
div.toastui-editor-md-preview {
display: none !Important;
}
div.toastui-editor.md-mode {
width: 100% !important;
}
#editor button.toastui-editor-toolbar-icons {
filter:unset;
pointer-events: all;
opacity: 1.0;
}
#editor.read-only button.toastui-editor-toolbar-icons {
filter:saturate(0) !Important;
pointer-events: none;
opacity: 0.3;
}
#editor button.actions {
background-image: none;
margin: 0;
}
#editor.read-only button.actions {
display: none;
}
#editor.read-only #toggleButton {
display: block !important;
}
.toastui-editor-defaultUI-toolbar > div:nth-child(5) {
flex: auto;
justify-content: flex-end;
}
menu {
display: none;
}

View File

@ -0,0 +1,119 @@
const editor = document.querySelector("#editor");
var toolBar = null;
var contents = null;
var pageContent = null;
var saveButton = null;
var editorUI = null;
isReadOnly = function() {
if (editor) {
return editor.className == 'read-only';
}
return undefined;
}
setReadOnly = function() {
pageContent.innerHTML = editorUI.getHTML();
editorUI.changeMode('wysiwig');
editorUI.blur();
editor.classList.add('read-only');
pageContent.contentEditable = false;
}
setEditable = function() {
editor.classList.remove('read-only');
pageContent.contentEditable = true;
editorUI.moveCursorToStart();
editorUI.focus();
}
makeMarkdownButton = function() {
button = document.createElement('button');
button.classList.add("toastui-editor-toolbar-icons");
button.classList.add("last");
button.ariaLabel = "Toggle Markdown";
button.style.backgroundImage = 'none';
button.innerHTML = 'MD';
button.style.margin = '0';
button.addEventListener('click', () => {
if (editorUI.isMarkdownMode()) {
editorUI.changeMode("wysiwig");
} else {
editorUI.changeMode("markdown");
}
});
return button;
};
makeSaveButton = function() {
const button = document.createElement('button');
button.className = 'actions';
button.innerHTML = 'save';
button.id = 'saveButton';
button.addEventListener('click', () => {
});
saveButton = button;
return button;
};
toggleButton = function() {
const button = document.createElement('button');
button.className = 'actions';
button.id = 'toggleButton';
button.innerHTML = 'edit';
button.addEventListener('click', () => {
if (isReadOnly()) {
setEditable();
} else {
setReadOnly();
}
});
return button;
}
handleContentChange = function() {
}
initialize = function() {
return new toastui.Editor({
el: editor,
initialEditType: 'wysiwyg',
initialValue: "",
hideModeSwitch : true,
previewStyle: 'vertical',
usageStatistics: false,
autofocus: false,
toolbarItems: [
['heading', 'bold', 'italic' ],
['ul', 'ol', 'indent', 'outdent'],
['table', 'image', 'link'],
[
{ el: makeMarkdownButton(), tooltip: 'Toggle MD' },
],
[
{ el: makeSaveButton(), command: 'save', tooltip: 'Save Changes' },
{ el: toggleButton(), tooltip: 'Toggle Edit Mode' }
],
],
events: {
'loadUI': function(e) {
editorUI = e;
pageContent = document.querySelector(".toastui-editor-ww-container > div > div");
toolBar = document.querySelector('.toastui-editor-toolbar');
e.setMarkdown(document.getElementById("data_form__body").value);
setReadOnly();
},
'changeMode': function() {
if (editor && Array(editor.classList).includes('read-only')) {
setReadOnly();
}
},
'change': handleContentChange,
}
});
};

View File

@ -16,6 +16,7 @@
--footer-height: 150px;
--breadcrumbs-height: 50px;
--wrapper-padding: 20px;
--main-height: calc(100vh - var(--nav-height) - var(--footer-height) - var(--breadcrumbs-height) + var(--wrapper-padding));
--max-width: calc(100vw - 20px);
--main-height: calc(100vh - var(--nav-height) - var(--footer-height) - var(--breadcrumbs-height));
--max-width: 1024px;
--min-width: 710px;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -142,11 +142,12 @@ def edit(table, path):
@app.web.before_request
def before_request():
g.messages = []
user_id = session.get("user_id", 1)
g.user = app.db.User.get(doc_id=user_id)
session["user_id"] = user_id
session["user"] = dict(g.user.serialize())
g.root = get_page(app.config.VIEW_URI)
if not request.path.startswith('/static'):
user_id = session.get("user_id", 1)
g.user = app.db.User.get(doc_id=user_id)
session["user_id"] = user_id
session["user"] = dict(g.user.serialize())
g.root = get_page(app.config.VIEW_URI)
@app.web.after_request