feat: v7.3.0 — cycle v6.8.0→v7.3.0 (Sites, Search, Automations, Calendar, SCIM, Wiki) + audit A9
- v6.8.0 Sites & Forms publics (migrations 24)
- v6.9.0 Recherche sémantique hybride + Ask AI (migration 25)
- v7.0.0 Automations v2 multi-étapes + Workers sandboxés (migration 26)
- v7.1.0 Calendar sync Google/CalDAV + Meeting Notes (migration 27)
- v7.2.0 Enterprise : SCIM 2.0, 2FA TOTP/passkeys, audit UI, agent approvals (migration 28)
- v7.3.0 Wiki/Teamspaces, verified pages, collab polish, charts, unfurl (migration 29)
- docs V68→V73, ROADMAP/CHANGELOG/WORKLOAD à jour, VERSION 7.3.0
- A9 : flowdeck.db, flowdeck_dev.db, test-commit.md, upload_test.txt et e2e/{node_modules,shots,test-results} désindexés + ignorés (.gitignore/.dockerignore)
This commit is contained in:
+48
-8
@@ -404,6 +404,33 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Teamspaces -->
|
||||
<div class="sidebar-section" x-show="isSectionVisible('teamspaces')" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100">
|
||||
<div class="sidebar-section-header" @click="toggleSection('teamspaces')" @contextmenu.prevent="openSectionMenu($event, 'teamspaces')">
|
||||
<div class="sidebar-section-title">
|
||||
<span class="chevron" :class="{ open: sectionsOpen.teamspaces }">▶</span>
|
||||
<span class="section-icon">{{ fd_icon("home",14) }}</span>
|
||||
<span class="section-label">Teamspaces</span>
|
||||
</div>
|
||||
<div class="sidebar-section-actions">
|
||||
<button class="section-action-btn" title="Refresh" @click.stop="loadTeamspaces()">{{ fd_icon("refresh",16) }}</button>
|
||||
<button class="section-action-btn section-menu-btn" title="Section options" @click.stop="openSectionMenu($event, 'teamspaces')">⋮</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-section-items" x-show="sectionsOpen.teamspaces" x-transition>
|
||||
<ul class="sidebar-items" data-section="teamspaces">
|
||||
<template x-for="t in teamspaces" :key="t.id">
|
||||
<li class="sidebar-item" @click="openTeamspace(t.id)">
|
||||
<span class="page-icon page-icon-svg">{{ fd_icon("home",16) }}</span>
|
||||
<span class="page-name" x-text="t.name"></span>
|
||||
<span class="page-name text-dim" style="font-size:11px;" x-text="t.item_count + (t.private ? ' · 🔒' : '')"></span>
|
||||
</li>
|
||||
</template>
|
||||
<li class="sidebar-item empty-hint" x-show="!teamspaces.length"><span class="page-icon page-icon-svg">{{ fd_icon("home",16) }}</span><span class="page-name text-dim">No teamspaces yet</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Shared -->
|
||||
<div class="sidebar-section" x-show="isSectionVisible('shared')" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100">
|
||||
<div class="sidebar-section-header" @click="toggleSection('shared')" @contextmenu.prevent="openSectionMenu($event, 'shared')">
|
||||
@@ -503,9 +530,10 @@
|
||||
</div>
|
||||
<div class="scp-list">
|
||||
<template x-for="(cfg, key) in (Object.keys(sidebarConfig).length ? sidebarConfig : {
|
||||
workspace:{visible:true,order:0},meetings:{visible:true,order:1},
|
||||
recents:{visible:true,order:2},favorites:{visible:true,order:3},
|
||||
agents:{visible:true,order:4},shared:{visible:true,order:5},published:{visible:true,order:6}
|
||||
workspace:{visible:true,order:0},teamspaces:{visible:true,order:1},
|
||||
meetings:{visible:true,order:2},recents:{visible:true,order:3},
|
||||
favorites:{visible:true,order:4},agents:{visible:true,order:5},
|
||||
shared:{visible:true,order:6},published:{visible:true,order:7}
|
||||
})" :key="key">
|
||||
<div class="scp-item" @click="toggleSectionVisibility(key)">
|
||||
<div class="scp-item-left">
|
||||
@@ -1098,6 +1126,7 @@
|
||||
window.appState = this;
|
||||
this.loadSidebarConfig();
|
||||
this.loadAgents();
|
||||
this.loadTeamspaces();
|
||||
this.initSidebarWidth();
|
||||
document.addEventListener('fd-toggle-sidebar', () => this.toggleSidebar());
|
||||
this.startClipAutoRefresh();
|
||||
@@ -1157,6 +1186,17 @@
|
||||
if(window.fdAgent && window.fdAgent.open){ window.fdAgent.open(); }
|
||||
else { document.dispatchEvent(new CustomEvent('fd-agent-toggle')); }
|
||||
},
|
||||
teamspaces: [],
|
||||
loadTeamspaces() {
|
||||
var self = this;
|
||||
fetch('/api/v2/wiki/teamspaces').then(function(r){ return r.json(); }).then(function(d){
|
||||
self.teamspaces = d.teamspaces || [];
|
||||
}).catch(function(){});
|
||||
},
|
||||
openTeamspace(id) {
|
||||
var target = '/wiki/teamspaces/' + id;
|
||||
if (window.fdNavigate) window.fdNavigate(target); else window.location = target;
|
||||
},
|
||||
sidebarCollapsed: false,
|
||||
sidebarPeek: false,
|
||||
mobileSidebarOpen: false,
|
||||
@@ -1310,7 +1350,7 @@
|
||||
|
||||
// ── Sections collapsible ──
|
||||
sectionsOpen: (function() {
|
||||
var def = { recents: true, private: true, meetings: true, favorites: true, agents: true, shared: true, published: true, apps: true, workspace: true, gitea: true };
|
||||
var def = { recents: true, private: true, meetings: true, favorites: true, agents: true, teamspaces: true, shared: true, published: true, apps: true, workspace: true, gitea: true };
|
||||
try {
|
||||
var saved = JSON.parse(localStorage.getItem('fd_sections') || '{}');
|
||||
return Object.assign(def, saved);
|
||||
@@ -1361,7 +1401,7 @@
|
||||
|
||||
getSectionOrder(key) {
|
||||
var cfg = this.sidebarConfig[key];
|
||||
var sections = ['workspace','gitea','meetings','recents','favorites','agents','shared','published'];
|
||||
var sections = ['workspace','gitea','meetings','recents','favorites','agents','teamspaces','shared','published'];
|
||||
if (cfg && typeof cfg.order === 'number') return cfg.order;
|
||||
return sections.indexOf(key);
|
||||
},
|
||||
@@ -1380,7 +1420,7 @@
|
||||
return (self.sidebarConfig[a] && self.sidebarConfig[a].order || 99) -
|
||||
(self.sidebarConfig[b] && self.sidebarConfig[b].order || 99);
|
||||
}) :
|
||||
['workspace','gitea','meetings','recents','favorites','agents','shared','published'];
|
||||
['workspace','gitea','meetings','recents','favorites','agents','teamspaces','shared','published'];
|
||||
var idx = sections.indexOf(key);
|
||||
if (idx < 0) return;
|
||||
var swapIdx = direction === 'up' ? idx - 1 : idx + 1;
|
||||
@@ -1422,7 +1462,7 @@
|
||||
getSectionIcon(key) {
|
||||
var icons = {
|
||||
workspace: '📁', meetings: '📅', recents: '🕐', favorites: '⭐',
|
||||
agents: '🤖', shared: '👥', published: '🌐', gitea: '🔗',
|
||||
agents: '🤖', teamspaces: '🏛️', shared: '👥', published: '🌐', gitea: '🔗',
|
||||
private: '🔒', library: '📚', 'my-tasks': '✅', marketplace: '🛒',
|
||||
help: '❓', trash: '🗑️'
|
||||
};
|
||||
@@ -1432,7 +1472,7 @@
|
||||
var labels = {
|
||||
workspace: 'Workspace', gitea: 'Repository (Gitea)', meetings: 'Meetings',
|
||||
recents: 'Recents', favorites: 'Favorites', agents: 'Agents',
|
||||
shared: 'Shared', published: 'Published', private: 'Private',
|
||||
teamspaces: 'Teamspaces', shared: 'Shared', published: 'Published', private: 'Private',
|
||||
library: 'Library', 'my-tasks': 'My Tasks', marketplace: 'Marketplace',
|
||||
help: 'Help', trash: 'Trash'
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user