fix: /local-workspace — final emoji sweep + view menu icons
FlowDeck CI / test (push) Failing after 4s
FlowDeck CI / docker (push) Has been skipped

- _fileIcon(): 📜→getSvgIcon('file') (JS/TS + code languages)
- Breadcrumb: ☰🏠←→📁✏→ SVG (chevron-right, home, chevron-left/right, folder, edit)
- View menu: +5 outline icons (folder, list, bar-chart, grid, align-left)
- View button: 🌳→viewMode text only
- Filter chips: 📄→getSvgIcon('file')
- Parent folder: 📂→folder SVG
- Context menu: 📄📂✏📋→file, folder, edit, copy SVG
- Drop overlay: 📥→download SVG
- _icons.html: +chevron-left, chevron-right, list, bar-chart, grid, align-left, corner-down-right, copy
- 143 tests passent
This commit is contained in:
2026-07-20 21:56:46 -04:00
parent fbd4b836f7
commit fff502a700
2 changed files with 40 additions and 22 deletions
+16
View File
@@ -52,6 +52,22 @@
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
{%- elif name == 'download' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
{%- elif name == 'chevron-left' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg>
{%- elif name == 'chevron-right' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
{%- elif name == 'list' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg>
{%- elif name == 'bar-chart' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg>
{%- elif name == 'grid' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
{%- elif name == 'align-left' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="17" y1="10" x2="3" y2="10"/><line x1="21" y1="6" x2="3" y2="6"/><line x1="17" y1="14" x2="3" y2="14"/><line x1="21" y1="18" x2="3" y2="18"/></svg>
{%- elif name == 'corner-down-right' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 10 20 15 15 20"/><path d="M4 4v7a4 4 0 0 0 4 4h12"/></svg>
{%- elif name == 'copy' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
{%- elif name == 'chevron-down' -%}
<svg width="{{s}}" height="{{s}}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>
{%- elif name == 'inbox' -%}
+24 -22
View File
@@ -1483,14 +1483,14 @@ window._wsInitData = (function() {
if (/\.pdf$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.(md|markdown)$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('edit',14)+'</span>';
if (/\.(py)$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.(js|jsx|ts|tsx)$/.test(n)) return '📜';
if (/\.(js|jsx|ts|tsx)$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.(html?|xml)$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.css$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.json$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.sql$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.(sh|bash|zsh)$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.ps1$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.(rs|go|java|rb|php|c|cpp|h|swift|kt|scala|r)$/.test(n)) return '📜';
if (/\.(rs|go|java|rb|php|c|cpp|h|swift|kt|scala|r)$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.(txt|log)$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
if (/\.(zip|tar|gz|rar|7z)$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
@@ -2097,7 +2097,7 @@ console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(wind
<!-- Drop overlay -->
<div class="drop-overlay" :class="{ active: isDragging }">
<div class="drop-hint">
<span class="icon">📥</span>
{{ fd_icon("download",16) }}
<div>Drop files here</div>
<div style="font-size:12px;color:var(--text-tertiary);margin-top:6px;" x-show="dropTarget">
Into: <strong x-text="dropTargetName"></strong>
@@ -2126,12 +2126,13 @@ console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(wind
<!-- Breadcrumb row -->
<div class="breadcrumb-row">
<button class="btn-icon nav-arrow" x-show="sidebarCollapsed" x-cloak @click="sidebarCollapsed = false" title="Show sidebar" style="margin-right:2px;">☰</button>
<a href="/workspaces" class="btn-icon nav-arrow" title="All workspaces">🏠</a>
<button class="btn-icon nav-arrow" @click="goBack()" title="Back" :disabled="!canGoBack">←</button>
<button class="btn-icon nav-arrow" @click="goForward()" title="Forward" :disabled="!canGoForward">→</button>
<button class="btn-icon nav-arrow" x-show="sidebarCollapsed" x-cloak @click="sidebarCollapsed = false" title="Show sidebar" style="margin-right:2px;">{{ fd_icon("chevron-right",16) }}</button>
<a href="/workspaces" class="btn-icon nav-arrow" title="All workspaces">{{ fd_icon("home",16) }}</a>
<button class="btn-icon nav-arrow" @click="goBack()" title="Back" :disabled="!canGoBack">{{ fd_icon("chevron-left",16) }}</button>
<button class="btn-icon nav-arrow" @click="goForward()" title="Forward" :disabled="!canGoForward">{{ fd_icon("chevron-right",16) }}</button>
{% if breadcrumbs %}
<div class="unified-breadcrumb">
<span class="bc-icon">📁</span>
<span class="bc-icon">{{ fd_icon("folder",14) }}</span>
<a href="/local-workspace" @click.prevent="navigateToRoot()" class="bc-root">{{ workspace_name }}</a>
<template x-for="(b, i) in folderStack" :key="'bc'+b.id">
<span style="display:contents;">
@@ -2146,26 +2147,27 @@ console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(wind
@keydown.enter="navigateToPath(), editingPath=false"
@keydown.escape="editingPath=false"
placeholder="/workspace/...">
<button class="bc-edit-go" @click="navigateToPath(), editingPath=false">→</button>
<button class="bc-edit-go" @click="navigateToPath(), editingPath=false">{{ fd_icon("corner-down-right",14) }}</button>
</div>
<button class="bc-edit-trigger" x-show="!editingPath" @click="startPathEdit()" title="Edit path">✎</button>
<button class="bc-edit-trigger" x-show="!editingPath" @click="startPathEdit()" title="Edit path">{{ fd_icon("edit",13) }}</button>
</div>
{% endif %}
</div>
<!-- Toolbar row -->
<div class="toolbar-row">
<div class="view-dropdown" @click.outside="viewMenuOpen=false" @keydown.escape="viewMenuOpen=false">
<button class="view-dropdown-btn" @click="viewMenuOpen=!viewMenuOpen" title="View">
<span x-text="viewIcons[viewMode] || '🌳'"></span>
<span x-text="viewMode"></span>
<span x-text="viewLabels[viewMode] || 'Tree'"></span>
<span class="dropdown-arrow">▾</span>
</button>
<div class="view-dropdown-menu" x-show="viewMenuOpen" x-transition @click="viewMenuOpen=false">
<button class="view-menu-item" :class="{ active: viewMode==='tree' }" @click="viewMode='tree', previewItem=null">Tree</button>
<button class="view-menu-item" :class="{ active: viewMode==='list' }" @click="viewMode='list', previewItem=null">List</button>
<button class="view-menu-item" :class="{ active: viewMode==='details' }" @click="viewMode='details', previewItem=null">Details</button>
<button class="view-menu-item" :class="{ active: viewMode==='title' }" @click="viewMode='title', previewItem=null">Cards</button>
<button class="view-menu-item" :class="{ active: viewMode==='content' }" @click="viewMode='content', previewItem=null">Content</button>
<button class="view-menu-item" :class="{ active: viewMode==='tree' }" @click="viewMode='tree', previewItem=null">{{ fd_icon("folder",14) }} Tree</button>
<button class="view-menu-item" :class="{ active: viewMode==='list' }" @click="viewMode='list', previewItem=null">{{ fd_icon("list",14) }} List</button>
<button class="view-menu-item" :class="{ active: viewMode==='details' }" @click="viewMode='details', previewItem=null">{{ fd_icon("bar-chart",14) }} Details</button>
<button class="view-menu-item" :class="{ active: viewMode==='title' }" @click="viewMode='title', previewItem=null">{{ fd_icon("grid",14) }} Cards</button>
<button class="view-menu-item" :class="{ active: viewMode==='content' }" @click="viewMode='content', previewItem=null">{{ fd_icon("align-left",14) }} Content</button>
</div>
</div>
<div class="search-bar-inline">
@@ -2205,7 +2207,7 @@ console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(wind
<button class="filter-chip" :class="{ active: filterType === 'pdf' }" @click="filterByType('pdf')" title="PDF" x-html="getSvgIcon('file',14)"></button>
<button class="filter-chip" :class="{ active: filterType === 'image' }" @click="filterByType('image')" title="Images" x-html="getSvgIcon('image',14)"></button>
<button class="filter-chip" :class="{ active: filterType === 'code' }" @click="filterByType('code')" title="Code" x-html="getSvgIcon('file',14)"></button>
<button class="filter-chip" :class="{ active: filterType === 'text' }" @click="filterByType('text')" title="Text">📄</button>
<button class="filter-chip" :class="{ active: filterType === 'text' }" @click="filterByType('text')" title="Text" x-html="getSvgIcon('file',14)"></button>
<span x-show="filterType || searchQuery" class="filter-clear" @click="filterType='', searchQuery='', doFilter()">✕ clear</span>
</div>
@@ -2214,7 +2216,7 @@ console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(wind
<li x-show="currentFolder > 0" style="list-style:none;">
<div class="ws-tree-item" @click="goToParent()" style="padding-left:4px;">
<span style="width:16px;flex-shrink:0;"></span>
<span class="icon">📂</span>
<span class="icon">{{ fd_icon("folder",16) }}</span>
<span class="name folder" style="font-weight:600;">..</span>
</div>
</li>
@@ -2540,10 +2542,10 @@ console.log('FLOWDECK v2.4.6 — IIFE done, _wsInitData keys:', Object.keys(wind
@click.outside="document.querySelector('.ctx-menu').style.display='none'"
@keydown.escape="document.querySelector('.ctx-menu').style.display='none'"
x-transition>
<div class="ctx-item" @click="ctxMenuOpenPage()">📄 Open</div>
<div class="ctx-item" x-show="ctxMenu.node && ctxMenu.node.is_folder" @click="ctxMenuOpenFolder()">📂 Open folder</div>
<div class="ctx-item" @click="ctxMenuRename()">✏️ Rename</div>
<div class="ctx-item" @click="ctxMenuDuplicate()">📋 Duplicate</div>
<div class="ctx-item" @click="ctxMenuOpenPage()">{{ fd_icon("file",14) }} Open</div>
<div class="ctx-item" x-show="ctxMenu.node && ctxMenu.node.is_folder" @click="ctxMenuOpenFolder()">{{ fd_icon("folder",14) }} Open folder</div>
<div class="ctx-item" @click="ctxMenuRename()">{{ fd_icon("edit",14) }} Rename</div>
<div class="ctx-item" @click="ctxMenuDuplicate()">{{ fd_icon("copy",14) }} Duplicate</div>
<div class="ctx-sep"></div>
<div class="ctx-section">🏷️ Tags</div>
<!-- Current tags with remove button -->