diff --git a/app/routers/board.py b/app/routers/board.py
index 3c6597a..3a3de30 100644
--- a/app/routers/board.py
+++ b/app/routers/board.py
@@ -216,6 +216,22 @@ def _load_children(parent_id: int) -> list:
return children
+def _local_workspaces_for_user(user: dict | None, workspace_id: int = 0) -> list[dict]:
+ """Return list of local workspaces for a user."""
+ if not user:
+ return []
+ try:
+ from app.db import get_conn
+ with get_conn() as conn:
+ rows = conn.execute(
+ "SELECT id, name FROM workspaces WHERE owner_id = ? ORDER BY name",
+ (user["id"],)
+ ).fetchall()
+ return [{"id": r["id"], "name": r["name"]} for r in rows]
+ except Exception:
+ return []
+
+
def _sidebar_data(request: Request, owner: str = "", repo: str = "") -> dict:
user = SessionManager.decode_session(request.cookies.get("flowdeck_session", ""))
ws_name = user.get("login", "Bruno") if user else "Bruno"
@@ -280,7 +296,7 @@ def _sidebar_data(request: Request, owner: str = "", repo: str = "") -> dict:
active = first
recent.append({
"id": f"{owner}/{repo}/{view}",
- "name": label, "icon": "π" if first else "Β·",
+ "name": label, "icon": "folder" if first else "",
"url": f"/board/{owner}/{repo}?view={view}",
"active": active, "indent": indent,
"depth": indent, "has_children": False, "children": [],
@@ -380,7 +396,9 @@ def _sidebar_data(request: Request, owner: str = "", repo: str = "") -> dict:
"auth_method": auth_method,
"gitea_linked": gitea_linked,
"github_linked": github_linked,
- "has_active_workspace": has_active_workspace}
+ "has_active_workspace": has_active_workspace,
+ "app_version": "4.0.3",
+ "local_workspaces": _local_workspaces_for_user(user)}
def _extract_ai_keywords(owner: str, repo: str, labels: list[dict], body: str = ""):
@@ -510,7 +528,7 @@ async def library_page(request: Request, owner: str = Query(default=""), repo: s
"icon": "π",
"url": f"/pages/{page['id']}",
"created_by": "You",
- "source": page.get("workspace") or "π Private",
+ "source": page.get("workspace") or "Private",
"last_edited": page.get("updated_at", "now"),
"last_visited": page.get("updated_at", "now"),
})
diff --git a/app/routers/dashboard.py b/app/routers/dashboard.py
index 1983258..4cc4072 100644
--- a/app/routers/dashboard.py
+++ b/app/routers/dashboard.py
@@ -31,6 +31,21 @@ def _get_user_or_redirect(request: Request):
return user
+def _local_workspaces_for_user(user: dict | None, workspace_id: int = 0) -> list[dict]:
+ """Return list of local workspaces for a user."""
+ if not user:
+ return []
+ try:
+ with get_conn() as conn:
+ rows = conn.execute(
+ "SELECT id, name FROM workspaces WHERE owner_id = ? ORDER BY name",
+ (user["id"],)
+ ).fetchall()
+ return [{"id": r["id"], "name": r["name"]} for r in rows]
+ except Exception:
+ return []
+
+
def _sidebar_data(request: Request, repos: list[dict], include_workspace: bool = True) -> dict:
user = SessionManager.decode_session(request.cookies.get("flowdeck_session", ""))
ws = user.get("login", "Bruno") if user else "Bruno"
@@ -176,19 +191,7 @@ def _sidebar_data(request: Request, repos: list[dict], include_workspace: bool =
"app_version": "4.0.3",
}
- # List local workspaces for user menu
- local_workspaces = []
- if user:
- try:
- with get_conn() as conn:
- ws_rows = conn.execute(
- "SELECT id, name FROM workspaces WHERE owner_id = ? ORDER BY name",
- (user["id"],)
- ).fetchall()
- local_workspaces = [{"id": r["id"], "name": r["name"]} for r in ws_rows]
- except Exception:
- pass
- sidebar["local_workspaces"] = local_workspaces
+ sidebar["local_workspaces"] = _local_workspaces_for_user(user)
return sidebar
diff --git a/app/templates/_header.html b/app/templates/_header.html
index f085e78..c98fdd6 100644
--- a/app/templates/_header.html
+++ b/app/templates/_header.html
@@ -67,7 +67,7 @@
@mouseleave="dragCloseTimer()">
-
+
@@ -110,7 +110,7 @@
-
+
›
diff --git a/app/templates/library.html b/app/templates/library.html
index 3837f36..93f77e7 100644
--- a/app/templates/library.html
+++ b/app/templates/library.html
@@ -1,10 +1,10 @@
{% extends "base.html" %}
-{% block page_icon %}π{% endblock %}
+{% block page_icon %}{{ fd_icon("book",18) }}{% endblock %}
{% block page_title %}Library{% endblock %}
{% block title_prefix %}Library{% endblock %}
{% block topbar %}
-{% set page_icon = "π" %}
+{% set page_icon = "book" %}
{% set page_title = "Library" %}
{% include '_header.html' %}
{% endblock %}
@@ -305,7 +305,7 @@
Loadingβ¦
-
π
+
{{ fd_icon("folder",32) }}
No workspace open
Open a workspace to browse and manage your library items.
Go to Workspaces
@@ -449,7 +449,7 @@
Loadingβ¦
-
π
+
{{ fd_icon("file",32) }}
No preview available
@@ -782,13 +782,13 @@ function libraryPage() {
},
// ββ Empty states ββ
- emptyIcon: 'π',
+ emptyIcon: 'file',
emptyTitle: 'No items',
emptyText: '',
_recomputeEmpty() {
- var icons = {recents:'π',favorites:'β',shared:'π₯',published:'π',private:'π',workspace:'π',repository:'π¦'};
- this.emptyIcon = icons[this.tab] || 'π';
+ var icons = {recents:'clock',favorites:'star',shared:'users',published:'globe',private:'lock',workspace:'folder',repository:'folder'};
+ this.emptyIcon = icons[this.tab] || 'file';
var titles = {recents:'No recent pages',favorites:'No favorites',shared:'No shared pages',
published:'No published pages',private:'No private pages',workspace:'No workspace pages',
repository:'Empty repository'};
diff --git a/app/templates/local_workspace.html b/app/templates/local_workspace.html
index ba6c869..459c12c 100644
--- a/app/templates/local_workspace.html
+++ b/app/templates/local_workspace.html
@@ -1,10 +1,10 @@
{% extends "base.html" %}
{% block page_title %}{{ workspace_name }}{% endblock %}
{% block title_prefix %}{{ workspace_name }}{% endblock %}
-{% block page_icon %}π{% endblock %}
+{% block page_icon %}{{ fd_icon("folder",18) }}{% endblock %}
{% block topbar %}
-{% set page_icon = "π" %}
+{% set page_icon = "folder" %}
{% set page_title = workspace_name %}
{% include '_header.html' %}
{% endblock %}
@@ -377,7 +377,7 @@ window._wsInitData = (function() {
sortBy: '',
viewMode: localStorage.getItem('fd_default_view') || 'tree',
viewMenuOpen: false,
- viewIcons: {tree:'π³',list:'π',details:'π',title:'π·οΈ',content:'π'},
+ viewIcons: {tree:'',list:'',details:'',title:'',content:''},
viewLabels: {tree:'Tree',list:'List',details:'Details',title:'Cards',content:'Content'},
// Context menu
@@ -677,7 +677,7 @@ window._wsInitData = (function() {
async _loadPreviewContent(node) {
if (node.is_folder) {
this.previewPanelContent = '
'
- + '
π'
+ + '
'+getSvgIcon('folder',32)+''
+ '
' + (node.child_count||0) + ' item(s)
'
+ '
Open folder'
+ '
';
@@ -719,7 +719,7 @@ window._wsInitData = (function() {
}
} catch(e) {}
preview = '
'
- + 'π'
+ + ''+getSvgIcon('file',32)+''
+ (node.size_display || '') + ' β open to view
';
} else if (format === 'blocks') {
try {
@@ -1475,23 +1475,23 @@ window._wsInitData = (function() {
// ββ File type icon ββ
_fileIcon(name, isFolder, contentFormat) {
- if (isFolder) return 'π';
+ if (isFolder) return '
'+getSvgIcon('folder',14)+'';
// FlowDeck internal pages (no extension, blocks/markdown format)
- if (contentFormat && contentFormat !== 'file') return 'π';
+ if (contentFormat && contentFormat !== 'file') return '
'+getSvgIcon('edit',14)+'';
var n = (name || '').toLowerCase();
if (/\.(png|jpe?g|gif|webp|svg|bmp|ico)$/.test(n)) return 'πΌοΈ';
if (/\.pdf$/.test(n)) return 'π';
- if (/\.(md|markdown)$/.test(n)) return 'π';
+ if (/\.(md|markdown)$/.test(n)) return '
'+getSvgIcon('edit',14)+'';
if (/\.(py)$/.test(n)) return 'π';
if (/\.(js|jsx|ts|tsx)$/.test(n)) return 'π';
if (/\.(html?|xml)$/.test(n)) return 'π';
if (/\.css$/.test(n)) return 'π¨';
- if (/\.json$/.test(n)) return 'π';
+ if (/\.json$/.test(n)) return '
'+getSvgIcon('file',14)+'';
if (/\.sql$/.test(n)) return 'ποΈ';
if (/\.(sh|bash|zsh)$/.test(n)) return 'π»';
if (/\.ps1$/.test(n)) return 'β‘';
if (/\.(rs|go|java|rb|php|c|cpp|h|swift|kt|scala|r)$/.test(n)) return 'π';
- if (/\.(txt|log)$/.test(n)) return 'π';
+ if (/\.(txt|log)$/.test(n)) return '
'+getSvgIcon('file',14)+'';
if (/\.(zip|tar|gz|rar|7z)$/.test(n)) return 'π¦';
return 'π';
},
diff --git a/app/templates/settings.html b/app/templates/settings.html
index f1485db..486278a 100644
--- a/app/templates/settings.html
+++ b/app/templates/settings.html
@@ -81,8 +81,8 @@
-
π€ My account
-
π Notifications
+
{{ fd_icon("user",14) }} My account
+
{{ fd_icon("bell",14) }} Notifications
π General
π·οΈ Tags
diff --git a/app/templates/workspaces.html b/app/templates/workspaces.html
index a13c4aa..9e30623 100644
--- a/app/templates/workspaces.html
+++ b/app/templates/workspaces.html
@@ -56,7 +56,7 @@
-
π My Workspaces
+
{{ fd_icon("folder",16) }} My Workspaces
diff --git a/static/css/app.css b/static/css/app.css
index 2449a55..2e4032d 100644
--- a/static/css/app.css
+++ b/static/css/app.css
@@ -524,6 +524,9 @@ input, select, textarea { font-family: inherit; color: inherit; }
.page-icon-svg svg {
vertical-align: middle;
}
+.nav-icon-inline { margin-right: 6px; vertical-align: middle; display: inline-flex; align-items: center; }
+.nav-icon-inline svg { vertical-align: middle; }
+.empty-state-icon { display: inline-flex; align-items: center; justify-content: center; margin-bottom: 12px; }
.sidebar-item:active .page-icon {
cursor: grabbing;