fix: Gitea sidebar tree + header actions inline with title
Gitea workspace sidebar: - loadSidebarTree() now uses innerHTML replacement instead of DOM manipulation (avoids Alpine reactivity overwrites) - Ensures workspace section is visible when tree loads - Shows error message when Gitea API fails (no token/gateway) - Better error handling with console.error catch Header actions inline: - page_editor: moved Edited/Share/Copy/Favorite/More buttons into the unified header (right_actions), accessible via window.E (editorState global reference set in init) - Removed duplicate page-topbar div from content area - Share dialog, More menu, and Activity popover stay in content area (triggered by header buttons via window.E references) - Gitea workspace: header now uses page-action-btn for consistency
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
{% block topbar %}
|
||||
{% set breadcrumb_items = [{"label": "Home", "url": "/workspaces"}, {"label": owner ~ "/" ~ repo, "url": None}] %}
|
||||
{% set page_icon = "🔗" %}
|
||||
{% set right_actions = '<button class="topbar-btn" @click="showNewFile=!showNewFile" title="New file">📄+</button><button class="topbar-btn" @click="triggerUpload()" title="Upload file">📤</button><input type="file" id="gitea-upload-input" style="display:none" @change="doUpload($event)" multiple><button class="topbar-btn" @click="refreshTree()" title="Refresh">🔄</button><a href="/accounts/settings" class="topbar-btn" title="Settings">⚙</a>' %}
|
||||
{% set right_actions = '<button class="page-action-btn" @click="showNewFile=!showNewFile" title="New file">📄+</button><button class="page-action-btn" @click="triggerUpload()" title="Upload file">📤</button><input type="file" id="gitea-upload-input" style="display:none" @change="doUpload($event)" multiple><button class="page-action-btn" @click="refreshTree()" title="Refresh">🔄</button><a href="/accounts/settings" class="topbar-btn" title="Settings">⚙</a>' %}
|
||||
{% include '_header.html' %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -310,63 +310,41 @@ function giteaWorkspace() {
|
||||
async loadSidebarTree() {
|
||||
try {
|
||||
var r = await fetch('/api/gitea/projects/' + this.owner + '/' + this.repo + '/tree');
|
||||
if (!r.ok) return;
|
||||
if (!r.ok) {
|
||||
// If API fails (e.g. no Gitea token), set a message
|
||||
var container = document.getElementById('sidebar-workspace-items');
|
||||
if (container) container.innerHTML = '<li class="sidebar-item empty-hint"><span class="page-icon">🔗</span><span class="page-name text-dim">Connect Gitea to browse files</span></li>';
|
||||
return;
|
||||
}
|
||||
var d = await r.json();
|
||||
var items = d.tree || [];
|
||||
var container = document.getElementById('sidebar-workspace-items');
|
||||
if (!container) return;
|
||||
// Ensure workspace section is visible
|
||||
if (window.appState && window.appState.sectionsOpen && !window.appState.sectionsOpen.workspace) {
|
||||
window.appState.sectionsOpen.workspace = true;
|
||||
}
|
||||
container.innerHTML = '';
|
||||
var self = this;
|
||||
items.forEach(function(item) {
|
||||
// Build tree HTML as string and set once (more performant)
|
||||
var html = '';
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
var icon = item.type === 'folder' ? '📁' : '📄';
|
||||
var li = document.createElement('li');
|
||||
li.className = 'sidebar-item';
|
||||
li.setAttribute('data-gitea-path', item.path);
|
||||
li.setAttribute('data-gitea-type', item.type === 'folder' ? 'folder' : 'file');
|
||||
li.setAttribute('data-gitea-sha', item.sha || '');
|
||||
li.style.cssText = 'padding-left:12px;cursor:pointer;display:flex;align-items:center;gap:4px;';
|
||||
// Checkbox (hidden by default, visible in multi-select mode)
|
||||
var cb = document.createElement('input');
|
||||
cb.type = 'checkbox';
|
||||
cb.className = 'gitea-checkbox';
|
||||
cb.style.cssText = 'flex-shrink:0;margin:0;display:none;';
|
||||
cb.addEventListener('click', function(ev) {
|
||||
ev.stopPropagation();
|
||||
self.selectItem(item.path, li, ev);
|
||||
});
|
||||
li.appendChild(cb);
|
||||
// Icon
|
||||
var iconSpan = document.createElement('span');
|
||||
iconSpan.className = 'page-icon';
|
||||
iconSpan.textContent = icon;
|
||||
li.appendChild(iconSpan);
|
||||
// Name (with double-click rename)
|
||||
var nameSpan = document.createElement('span');
|
||||
nameSpan.className = 'page-name';
|
||||
nameSpan.textContent = item.name;
|
||||
nameSpan.addEventListener('dblclick', function(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
self.startInlineRename(nameSpan, item.path, li);
|
||||
});
|
||||
li.appendChild(nameSpan);
|
||||
container.appendChild(li);
|
||||
});
|
||||
html += '<li class="sidebar-item" data-gitea-path="' + item.path + '" data-gitea-type="' + (item.type === 'folder' ? 'folder' : 'file') + '" data-gitea-sha="' + (item.sha || '') + '" style="padding-left:12px;cursor:pointer;display:flex;align-items:center;gap:4px;">';
|
||||
html += '<span class="page-icon">' + icon + '</span>';
|
||||
html += '<span class="page-name">' + item.name + '</span>';
|
||||
html += '</li>';
|
||||
}
|
||||
// Add Private Pages link
|
||||
var sep = document.createElement('li');
|
||||
sep.style.cssText = 'border-top:1px solid var(--border);margin:8px 0;';
|
||||
container.appendChild(sep);
|
||||
var pli = document.createElement('li');
|
||||
pli.className = 'sidebar-item';
|
||||
pli.style.cssText = 'padding-left:12px;cursor:pointer;';
|
||||
pli.innerHTML = '<span class="page-icon">🔒</span><span class="page-name">Private Pages</span>';
|
||||
pli.addEventListener('click', function(e) {
|
||||
e.preventDefault(); e.stopPropagation();
|
||||
self.showPrivate = true; self.showFile = false; self.showEditor = false;
|
||||
self.loadPrivatePages();
|
||||
});
|
||||
container.appendChild(pli);
|
||||
} catch(e) { console.error('Sidebar tree load failed:', e); }
|
||||
html += '<li style="border-top:1px solid var(--border);margin:8px 0;"></li>';
|
||||
html += '<li class="sidebar-item" id="gitea-private-link" style="padding-left:12px;cursor:pointer;display:flex;align-items:center;gap:4px;">';
|
||||
html += '<span class="page-icon">🔒</span><span class="page-name">Private Pages</span></li>';
|
||||
container.innerHTML = html;
|
||||
// Re-attach event listeners
|
||||
this.setupSidebarClicks();
|
||||
} catch(e) {
|
||||
console.error('Gitea sidebar tree load failed:', e);
|
||||
}
|
||||
},
|
||||
|
||||
setupSidebarClicks() {
|
||||
|
||||
@@ -2,35 +2,11 @@
|
||||
page_title %}{{ page.title }}{% endblock %} {% block topbar %}
|
||||
{% set page_icon = "📄" %}
|
||||
{% set page_title = page.title %}
|
||||
{% set right_actions = '<span class="topbar-edited" style="cursor:pointer;" @click="window.E && (window.E.activityOpen = !window.E.activityOpen)">Edited <span x-text="window.E && window.E.timeAgo || \'\'"></span> ▾</span><button class="topbar-btn share-btn" @click="window.E && (window.E.shareOpen = !window.E.shareOpen)">🔒 Share ▾</button><button class="topbar-btn" @click="window.E && window.E.copyPageLink()" title="Copy link">🔗</button><button class="topbar-btn star-btn" @click="window.E && window.E.toggleFavorite()">⭐</button><button class="topbar-btn" @click="window.E && (window.E.moreOpen = !window.E.moreOpen)" style="position:relative">⋯</button>' %}
|
||||
{% include '_header.html' %}
|
||||
{% endblock %} {% block content %}
|
||||
<div class="page-editor-wrapper" x-data="editorState()">
|
||||
<!-- ═══════════ Action Bar (Share, Copy, Favorite, More) ═══════════ -->
|
||||
<div class="page-topbar">
|
||||
<div class="page-topbar-right" style="position: relative">
|
||||
<span class="topbar-edited" style="cursor:pointer;" @click="activityOpen = !activityOpen">Edited <span x-text="timeAgo"></span> ▾</span>
|
||||
<button
|
||||
class="page-action-btn share-btn"
|
||||
@click="shareOpen = !shareOpen"
|
||||
>
|
||||
🔒 Share <span class="chevron-down">▾</span>
|
||||
</button>
|
||||
<button
|
||||
class="page-action-btn"
|
||||
@click="copyPageLink"
|
||||
title="Copy link"
|
||||
>
|
||||
🔗
|
||||
</button>
|
||||
<button class="page-action-btn star-btn" @click="toggleFavorite">
|
||||
<span
|
||||
x-text="favorited ? '⭐' : '☆'"
|
||||
:class="{ starred: favorited }"
|
||||
></span>
|
||||
</button>
|
||||
<button class="page-action-btn" @click="moreOpen = !moreOpen">
|
||||
⋮
|
||||
</button>
|
||||
<!-- Share/More dialogs (in content area, triggered by header buttons) -->
|
||||
|
||||
<!-- ═══════════ Share / Publish Dialog ═══════════ -->
|
||||
<div
|
||||
@@ -410,8 +386,6 @@ page_title %}{{ page.title }}{% endblock %} {% block topbar %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════ Page Content ═══════════ -->
|
||||
<div class="page-cover-area">
|
||||
|
||||
Reference in New Issue
Block a user