From 681f802e9ca27cbd0ed92271cce61b8c7d648485 Mon Sep 17 00:00:00 2001 From: Yaro Kasear Date: Tue, 19 Aug 2025 16:08:44 -0500 Subject: [PATCH] Refactor editor and template components to enhance functionality and improve code structure --- inventory/static/js/editor.js | 101 ++++++++++-------- inventory/templates/coffee.html | 9 +- .../templates/fragments/_editor_fragment.html | 28 +++-- inventory/templates/inventory.html | 10 +- inventory/templates/layout.html | 12 +-- inventory/templates/worklog.html | 6 +- inventory/ui/blueprint.py | 31 ++++++ inventory/ui/defaults.py | 22 ++++ 8 files changed, 151 insertions(+), 68 deletions(-) diff --git a/inventory/static/js/editor.js b/inventory/static/js/editor.js index 22323e2..0c335b8 100644 --- a/inventory/static/js/editor.js +++ b/inventory/static/js/editor.js @@ -1,44 +1,61 @@ -document.addEventListener("DOMContentLoaded", () => { - document.querySelectorAll('.editor').forEach(el => { - EditorWidget.autoResizeTextarea(el); - }); - - document.querySelectorAll('.viewer').forEach(el => { - const id = el.id.replace('viewer', ''); - const textEditor = document.getElementById(`textEditor${id}`); - if (textEditor) { - el.innerHTML = marked.parse(textEditor.value); - } - }); -}); - -const EditorWidget = (() => { - let tempIdCounter = 1; - - function autoResizeTextarea(textarea) { - textarea.style.height = 'auto'; - textarea.style.height = `${textarea.scrollHeight + 2}px`; - } - - function createEditorWidget(template, id, timestamp, content = '') { - let html = template.innerHTML - .replace(/__ID__/g, id) - .replace(/__TIMESTAMP__/g, timestamp) - .replace(/__CONTENT__/g, content); - - const wrapper = document.createElement("div"); - wrapper.innerHTML = html; - - return wrapper.firstElementChild; - } - - function createTempId(prefix = "temp") { - return `${prefix}-${tempIdCounter++}`; - } - +function Editor(cfg) { return { - autoResizeTextarea, - createEditorWidget, - createTempId + id: cfg.id, + refreshUrl: cfg.refreshUrl, + updateUrl: cfg.updateUrl, + createUrl: cfg.createUrl, + deleteUrl: cfg.deleteUrl, + updateUrl: cfg.updateUrl, + fieldName: cfg.fieldName, + recordId: cfg.recordId, + + init() { + // initial render from whatever’s in the textarea + this.renderViewer(); + // then pull server value and re-render + if (this.refreshUrl) this.refresh(); + }, + + buildRefreshUrl() { + if (!this.refreshUrl) return null; + const u = new URL(this.refreshUrl, window.location.origin); + u.search = new URLSearchParams({ field: this.fieldName, id: this.recordId }).toString(); + return u.toString(); + }, + + async refresh() { + const url = this.buildRefreshUrl(); + if (!url) return; + const res = await fetch(url, { headers: { 'HX-Request': 'true' } }); + const text = await res.text(); + if (this.$refs.editor) { + this.$refs.editor.value = text; + this.resizeEditor(); + this.renderViewer(); + } + }, + + triggerRefresh() { + // use this anywhere to force a re-pull + this.$refs.container?.dispatchEvent(new CustomEvent('editor:refresh', { bubbles: true })); + }, + + openEditTab() { + this.$nextTick(() => { this.resizeEditor(); this.renderViewer(); }); + }, + + resizeEditor() { + const ta = this.$refs.editor; + if (!ta) return; + ta.style.height = 'auto'; + ta.style.height = `${ta.scrollHeight + 2}px`; + }, + + renderViewer() { + const ta = this.$refs.editor, viewer = this.$refs.viewer; + if (!viewer || !ta) return; + const raw = ta.value || ''; + viewer.innerHTML = (window.marked ? marked.parse(raw) : raw); + } }; -})(); +} diff --git a/inventory/templates/coffee.html b/inventory/templates/coffee.html index 4ae9b20..fd0dd1b 100644 --- a/inventory/templates/coffee.html +++ b/inventory/templates/coffee.html @@ -32,6 +32,7 @@ {% block script %} var score = {{ score }}; + var initialScore = score; const gridSize = {{ level + 3 }}; var clickOrder = {}; var clickCounter = 0; @@ -44,10 +45,9 @@ (clickOrder[key] ??= []).push(clickCounter); }); - const bestScore = Object.values(clickOrder) + let bestScore = Object.values(clickOrder) .reduce((n, arr) => n + (arr.length & 1), 0); - document.getElementById('best_score').textContent = `Perfect Clicks: ${bestScore}`; Object.entries(clickOrder).forEach(([key, value]) => { @@ -107,7 +107,10 @@ const allUnchecked = Array.from(document.querySelectorAll('.form-check-input')).every(cb => !cb.checked); if (allChecked && !window.__alreadyNavigated && {{ level }} < 51) { window.__alreadyNavigated = true; - location.href = `{{ url_for('main.coffee', level=level + 1) | safe }}&score=${score - bestScore}`; + if ((score - bestScore) == initialScore) { + bestScore *= 2; + } + location.href = `{{ url_for('main.coffee', level=level + 1) | safe }}&score=${Math.max(score - bestScore, 0)}`; } else if (allUnchecked && !window.__alreadyNavigated && {{ level }} > -2) { window.__alreadyNavigated = true; location.href = `{{ url_for('main.coffee', level=level - 1) | safe }}&score=${score + bestScore}`; diff --git a/inventory/templates/fragments/_editor_fragment.html b/inventory/templates/fragments/_editor_fragment.html index 97e2027..e80779f 100644 --- a/inventory/templates/fragments/_editor_fragment.html +++ b/inventory/templates/fragments/_editor_fragment.html @@ -1,8 +1,17 @@ {% import "fragments/_icon_fragment.html" as icons %} -{% macro render_editor(id, title, mode='edit', content=None, enabled=True) %} +{% macro dynamic_editor(id, title, mode='edit', content=none, enabled=true, create_url=none, refresh_url=none, +update_url=none, delete_url=none, field_name=none, record_id=none) %} -
+
+ id="viewer{{ id }}" x-ref="viewer">
- + data-note-id="{{ id }}" @input="resizeEditor(); renderViewer()">{{ content if content }}
diff --git a/inventory/templates/inventory.html b/inventory/templates/inventory.html index 623964c..24c8287 100644 --- a/inventory/templates/inventory.html +++ b/inventory/templates/inventory.html @@ -247,12 +247,14 @@
- {{ editor.render_editor( + {{ editor.dynamic_editor( id = "notes", title = "Notes & Comments", mode = 'view' if item.id else 'edit', - content = item.notes if item.notes else '', - enabled = item.condition not in ["Removed", "Disposed"] + enabled = item.condition not in ["Removed", "Disposed"], + refresh_url = url_for('ui.get_value', model_name='inventory'), + field_name='notes', + record_id=item.id ) }}
{% if worklog %} @@ -278,7 +280,7 @@ {% set title %} {{ note.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}{{ links.entry_link('worklog_entry', note.work_log_id) }} {% endset %} - {{ editor.render_editor( + {{ editor.dynamic_editor( id = 'updates' + (note.id | string), title = title, content = note.content, diff --git a/inventory/templates/layout.html b/inventory/templates/layout.html index 41b5250..67feb6b 100644 --- a/inventory/templates/layout.html +++ b/inventory/templates/layout.html @@ -65,6 +65,12 @@
{% block content %}{% endblock %}
+ + + + + + @@ -79,12 +85,6 @@ - - - - - -