feat(v1.3.0): Step 2 — DB tables collections, collection_pages, collection_views
- Ajout des 3 nouvelles tables pour le Database Concept - collections: base de données abstraite, indépendante de Gitea - collection_pages: pages génériques avec parent_id et property_values_json - collection_views: vues configurables par collection - Mise à jour test_db_tables_exist pour inclure les nouvelles tables - 28/28 tests passent
This commit is contained in:
+46
-55
@@ -10,7 +10,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Library tabs: Recents | Favorites | Shared | Private -->
|
||||
<!-- Library tabs -->
|
||||
<div class="view-tabs" x-data="{ tab: 'recents' }">
|
||||
<button class="view-tab" :class="{ active: tab === 'recents' }" @click="tab = 'recents'">
|
||||
<span class="tab-icon">🕒</span> Recents
|
||||
@@ -29,78 +29,76 @@
|
||||
<!-- Toolbar -->
|
||||
<div class="view-toolbar">
|
||||
<div class="view-toolbar-spacer"></div>
|
||||
<button class="toolbar-btn" title="Filter">☰</button>
|
||||
<button class="toolbar-btn" title="Search">🔍</button>
|
||||
<button class="toolbar-btn" title="Properties">⫶</button>
|
||||
<button class="btn-new" @click="newPage()">New page</button>
|
||||
</div>
|
||||
|
||||
<!-- Library content -->
|
||||
<div x-data="libraryData()" style="padding: 0 24px;">
|
||||
<!-- Table headers -->
|
||||
<div style="display:flex; padding: 8px 12px; border-bottom:1px solid var(--border); font-size:12px; font-weight:600; color:var(--text-dim);">
|
||||
<span style="flex:1;">Page name</span>
|
||||
<span style="width:160px;">Last edited time</span>
|
||||
<!-- Table -->
|
||||
<div x-data="{ tab: 'recents' }" style="padding: 0 24px;">
|
||||
<!-- Column headers -->
|
||||
<div class="library-table-header">
|
||||
<span class="lib-col lib-col-name">📄 Page name</span>
|
||||
<span class="lib-col lib-col-author">👤 Created by</span>
|
||||
<span class="lib-col lib-col-source">↗ Source</span>
|
||||
<span class="lib-col lib-col-edited">🕒 Last edited time</span>
|
||||
<span class="lib-col lib-col-visited">🕒 Last visited time</span>
|
||||
</div>
|
||||
|
||||
<!-- Recents tab -->
|
||||
{% macro page_row(page) %}
|
||||
<a href="{{ page.url }}" class="library-table-row">
|
||||
<span class="lib-col lib-col-name">
|
||||
<span class="page-icon">{{ page.icon }}</span>
|
||||
<span>{{ page.name }}</span>
|
||||
</span>
|
||||
<span class="lib-col lib-col-author">👤 {{ page.created_by or 'You' }}</span>
|
||||
<span class="lib-col lib-col-source">{{ page.source or '🔒 Private' }}</span>
|
||||
<span class="lib-col lib-col-edited">{{ page.last_edited }}</span>
|
||||
<span class="lib-col lib-col-visited">{{ page.last_visited or page.last_edited }}</span>
|
||||
</a>
|
||||
{% endmacro %}
|
||||
|
||||
<!-- Recents -->
|
||||
<div x-show="tab === 'recents'">
|
||||
{% for page in recent_pages %}
|
||||
<a href="{{ page.url }}" style="display:flex; align-items:center; padding:8px 12px; text-decoration:none; color:var(--text-primary); border-radius:6px; transition:background 0.15s;"
|
||||
onmouseover="this.style.background='var(--bg-hover)'" onmouseout="this.style.background='transparent'">
|
||||
<span style="font-size:16px; margin-right:10px;">{{ page.icon }}</span>
|
||||
<span style="flex:1;">{{ page.name }}</span>
|
||||
<span style="width:160px; font-size:13px; color:var(--text-dim);">{{ page.last_edited }}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% for page in recent_pages %}{{ page_row(page) }}{% endfor %}
|
||||
{% if not recent_pages %}
|
||||
<div style="text-align:center; padding:48px; color:var(--text-dim);">
|
||||
<div style="font-size:48px; margin-bottom:16px;">🕒</div>
|
||||
<div class="lib-empty">
|
||||
<div style="font-size:48px;margin-bottom:16px;">🕒</div>
|
||||
<h3>No recent pages</h3>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Favorites tab -->
|
||||
<!-- Favorites -->
|
||||
<div x-show="tab === 'favorites'">
|
||||
{% for page in favorite_pages %}
|
||||
<a href="{{ page.url }}" style="display:flex; align-items:center; padding:8px 12px; text-decoration:none; color:var(--text-primary); border-radius:6px;"
|
||||
onmouseover="this.style.background='var(--bg-hover)'" onmouseout="this.style.background='transparent'">
|
||||
<span style="font-size:16px; margin-right:10px;">{{ page.icon }}</span>
|
||||
<span style="flex:1;">{{ page.name }}</span>
|
||||
<span style="width:160px; font-size:13px; color:var(--text-dim);">{{ page.last_edited }}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% for page in favorite_pages %}{{ page_row(page) }}{% endfor %}
|
||||
{% if not favorite_pages %}
|
||||
<div style="text-align:center; padding:48px; color:var(--text-dim);">
|
||||
<div style="font-size:48px; margin-bottom:16px;">⭐</div>
|
||||
<div class="lib-empty">
|
||||
<div style="font-size:48px;margin-bottom:16px;">⭐</div>
|
||||
<h3>No favorites</h3>
|
||||
<p style="margin-top:8px;">Right-click a page in the sidebar and select "Add to Favorites".</p>
|
||||
<p>Right-click a page in the sidebar and select "Add to Favorites".</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Shared tab -->
|
||||
<!-- Shared -->
|
||||
<div x-show="tab === 'shared'">
|
||||
<div style="text-align:center; padding:48px; color:var(--text-dim);">
|
||||
<div style="font-size:48px; margin-bottom:16px;">👥</div>
|
||||
<div class="lib-empty">
|
||||
<div style="font-size:48px;margin-bottom:16px;">👥</div>
|
||||
<h3>No shared pages</h3>
|
||||
<p style="margin-top:8px;">Shared pages from your team will appear here.</p>
|
||||
<p>Shared pages from your team will appear here.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Private tab -->
|
||||
<!-- Private -->
|
||||
<div x-show="tab === 'private'">
|
||||
{% for page in private_pages %}
|
||||
<a href="{{ page.url }}" style="display:flex; align-items:center; padding:8px 12px; text-decoration:none; color:var(--text-primary); border-radius:6px;"
|
||||
onmouseover="this.style.background='var(--bg-hover)'" onmouseout="this.style.background='transparent'">
|
||||
<span style="font-size:16px; margin-right:10px;">{{ page.icon }}</span>
|
||||
<span style="flex:1;">{{ page.name }}</span>
|
||||
<span style="width:160px; font-size:13px; color:var(--text-dim);">{{ page.last_edited }}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% for page in private_pages %}{{ page_row(page) }}{% endfor %}
|
||||
{% if not private_pages %}
|
||||
<div style="text-align:center; padding:48px; color:var(--text-dim);">
|
||||
<div style="font-size:48px; margin-bottom:16px;">🔒</div>
|
||||
<div class="lib-empty">
|
||||
<div style="font-size:48px;margin-bottom:16px;">🔒</div>
|
||||
<h3>No private pages</h3>
|
||||
<p style="margin-top:8px;">Create a new page with the + button in the sidebar.</p>
|
||||
<p>Create a new page with the + button in the sidebar.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -109,18 +107,11 @@
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
function libraryData() {
|
||||
return {
|
||||
get tab() { return document.querySelector('[x-data]').__x.$data.tab; }
|
||||
};
|
||||
}
|
||||
|
||||
function newPage() {
|
||||
const csrf = document.cookie.match(/csrf_token=([^;]+)/);
|
||||
const token = csrf ? csrf[1] : '';
|
||||
fetch('/board/api/pages?title=New%20page§ion=Private', {
|
||||
fetch('/board/api/pages?section=Private', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-Token': token }
|
||||
headers: { 'X-CSRF-Token': csrf ? csrf[1] : '' }
|
||||
})
|
||||
.then(r => { if (!r.ok) throw new Error('CSRF error'); return r.json(); })
|
||||
.then(data => { window.location.href = `/pages/${data.id}`; })
|
||||
|
||||
Reference in New Issue
Block a user