From 724ff4c880e4e4cf0bb03a08272bb231836631cc Mon Sep 17 00:00:00 2001 From: bruno Date: Tue, 14 Jul 2026 12:23:05 -0400 Subject: [PATCH] feat(v4.0): wire Share/Publish modal with real API calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - publishPage() → POST /api/pages/{id}/publish - unpublishPage() → DELETE /api/pages/{id}/publish - shareInvite() → POST /api/pages/{id}/share - loadShares() → GET /api/pages/{id}/shares - removeShare() → DELETE /api/pages/{id}/share/{sid} - All buttons now call real API instead of local state toggle --- app/templates/page_editor.html | 60 +++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/app/templates/page_editor.html b/app/templates/page_editor.html index cce88c9..c5fac7b 100644 --- a/app/templates/page_editor.html +++ b/app/templates/page_editor.html @@ -75,9 +75,9 @@ page_title %}{{ page.title }}{% endblock %} {% block topbar %} class="sd-input" placeholder="Add people, groups or emails..." x-model="inviteEmail" - @keydown.enter="invitePerson" + @keydown.enter="shareInvite()" /> - @@ -268,7 +268,7 @@ page_title %}{{ page.title }}{% endblock %} {% block topbar %}

@@ -354,7 +354,7 @@ page_title %}{{ page.title }}{% endblock %} {% block topbar %} @@ -657,6 +657,58 @@ page_title %}{{ page.title }}{% endblock %} {% block topbar %} clearTimeout(this._toastTimer); this._toastTimer = setTimeout(() => { this.toastVisible = false; }, 2500); }, + publishPage() { + var self = this; + var csrf = document.cookie.match(/csrf_token=([^;]+)/); + fetch('/api/pages/' + this.pid + '/publish', { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf ? csrf[1] : '' } + }).then(function(r){ return r.json(); }).then(function(d){ + if (d.status === 'ok') { self.pagePublished = true; self.publishedUrl = d.url || self.publishedUrl; self.showToast('Published to web'); } + else { self.showToast(d.detail || 'Publish failed'); } + }).catch(function(){ self.showToast('Publish failed'); }); + }, + unpublishPage() { + var self = this; + var csrf = document.cookie.match(/csrf_token=([^;]+)/); + fetch('/api/pages/' + this.pid + '/publish', { + method: 'DELETE', + headers: { 'X-CSRF-Token': csrf ? csrf[1] : '' } + }).then(function(r){ return r.json(); }).then(function(d){ + if (d.status === 'ok') { self.pagePublished = false; self.publishedUrl = ''; self.showToast('Unpublished'); } + else { self.showToast(d.detail || 'Unpublish failed'); } + }).catch(function(){ self.showToast('Unpublish failed'); }); + }, + shareInvite() { + var self = this; + if (!this.inviteEmail.trim()) return; + var csrf = document.cookie.match(/csrf_token=([^;]+)/); + fetch('/api/pages/' + this.pid + '/share', { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf ? csrf[1] : '' }, + body: JSON.stringify({ email: this.inviteEmail.trim(), permission: this.invitePermission }) + }).then(function(r){ return r.json(); }).then(function(d){ + if (d.status === 'ok') { self.inviteEmail = ''; self.showToast('Invitation sent'); self.loadShares(); } + else { self.showToast(d.detail || 'Share failed'); } + }).catch(function(){ self.showToast('Share failed'); }); + }, + loadShares() { + var self = this; + fetch('/api/pages/' + this.pid + '/shares').then(function(r){ return r.json(); }).then(function(d){ + self.accessList = d.shares || []; + }).catch(function(){ self.accessList = []; }); + }, + removeShare(sid) { + var self = this; + var csrf = document.cookie.match(/csrf_token=([^;]+)/); + fetch('/api/pages/' + this.pid + '/share/' + sid, { + method: 'DELETE', + headers: { 'X-CSRF-Token': csrf ? csrf[1] : '' } + }).then(function(r){ return r.json(); }).then(function(d){ + if (d.status === 'ok') { self.showToast('Share removed'); self.loadShares(); } + else { self.showToast(d.detail || 'Remove failed'); } + }).catch(function(){ self.showToast('Remove failed'); }); + }, invitePerson(){if(!this.inviteEmail.trim())return;this.accessList.push({email:this.inviteEmail,permission:this.invitePermission,permOpen:false});this.inviteEmail='';}, removeAccess(email){this.accessList=this.accessList.filter(a=>a.email!==email);}, exportPage(){this.moreOpen=false;},