fix: /local-workspace — final emoji sweep + view menu icons
- _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:
@@ -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>
|
<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' -%}
|
{%- 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>
|
<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' -%}
|
{%- 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>
|
<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' -%}
|
{%- elif name == 'inbox' -%}
|
||||||
|
|||||||
@@ -1483,14 +1483,14 @@ window._wsInitData = (function() {
|
|||||||
if (/\.pdf$/.test(n)) return '<span class="page-icon-svg">'+getSvgIcon('file',14)+'</span>';
|
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 (/\.(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 (/\.(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 (/\.(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 (/\.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 (/\.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 (/\.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 (/\.(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 (/\.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 (/\.(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>';
|
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>';
|
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 -->
|
<!-- Drop overlay -->
|
||||||
<div class="drop-overlay" :class="{ active: isDragging }">
|
<div class="drop-overlay" :class="{ active: isDragging }">
|
||||||
<div class="drop-hint">
|
<div class="drop-hint">
|
||||||
<span class="icon">📥</span>
|
{{ fd_icon("download",16) }}
|
||||||
<div>Drop files here</div>
|
<div>Drop files here</div>
|
||||||
<div style="font-size:12px;color:var(--text-tertiary);margin-top:6px;" x-show="dropTarget">
|
<div style="font-size:12px;color:var(--text-tertiary);margin-top:6px;" x-show="dropTarget">
|
||||||
Into: <strong x-text="dropTargetName"></strong>
|
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 -->
|
<!-- Breadcrumb row -->
|
||||||
<div class="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>
|
<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">🏠</a>
|
<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">←</button>
|
<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">→</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">
|
<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>
|
<a href="/local-workspace" @click.prevent="navigateToRoot()" class="bc-root">{{ workspace_name }}</a>
|
||||||
<template x-for="(b, i) in folderStack" :key="'bc'+b.id">
|
<template x-for="(b, i) in folderStack" :key="'bc'+b.id">
|
||||||
<span style="display:contents;">
|
<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.enter="navigateToPath(), editingPath=false"
|
||||||
@keydown.escape="editingPath=false"
|
@keydown.escape="editingPath=false"
|
||||||
placeholder="/workspace/...">
|
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>
|
</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>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Toolbar row -->
|
<!-- Toolbar row -->
|
||||||
<div class="toolbar-row">
|
<div class="toolbar-row">
|
||||||
<div class="view-dropdown" @click.outside="viewMenuOpen=false" @keydown.escape="viewMenuOpen=false">
|
<div class="view-dropdown" @click.outside="viewMenuOpen=false" @keydown.escape="viewMenuOpen=false">
|
||||||
<button class="view-dropdown-btn" @click="viewMenuOpen=!viewMenuOpen" title="View">
|
<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 x-text="viewLabels[viewMode] || 'Tree'"></span>
|
||||||
<span class="dropdown-arrow">▾</span>
|
<span class="dropdown-arrow">▾</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="view-dropdown-menu" x-show="viewMenuOpen" x-transition @click="viewMenuOpen=false">
|
<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==='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">List</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">Details</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">Cards</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">Content</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>
|
</div>
|
||||||
<div class="search-bar-inline">
|
<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 === '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 === '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 === '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>
|
<span x-show="filterType || searchQuery" class="filter-clear" @click="filterType='', searchQuery='', doFilter()">✕ clear</span>
|
||||||
</div>
|
</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;">
|
<li x-show="currentFolder > 0" style="list-style:none;">
|
||||||
<div class="ws-tree-item" @click="goToParent()" style="padding-left:4px;">
|
<div class="ws-tree-item" @click="goToParent()" style="padding-left:4px;">
|
||||||
<span style="width:16px;flex-shrink:0;"></span>
|
<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>
|
<span class="name folder" style="font-weight:600;">..</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</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'"
|
@click.outside="document.querySelector('.ctx-menu').style.display='none'"
|
||||||
@keydown.escape="document.querySelector('.ctx-menu').style.display='none'"
|
@keydown.escape="document.querySelector('.ctx-menu').style.display='none'"
|
||||||
x-transition>
|
x-transition>
|
||||||
<div class="ctx-item" @click="ctxMenuOpenPage()">📄 Open</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()">📂 Open folder</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()">✏️ Rename</div>
|
<div class="ctx-item" @click="ctxMenuRename()">{{ fd_icon("edit",14) }} Rename</div>
|
||||||
<div class="ctx-item" @click="ctxMenuDuplicate()">📋 Duplicate</div>
|
<div class="ctx-item" @click="ctxMenuDuplicate()">{{ fd_icon("copy",14) }} Duplicate</div>
|
||||||
<div class="ctx-sep"></div>
|
<div class="ctx-sep"></div>
|
||||||
<div class="ctx-section">🏷️ Tags</div>
|
<div class="ctx-section">🏷️ Tags</div>
|
||||||
<!-- Current tags with remove button -->
|
<!-- Current tags with remove button -->
|
||||||
|
|||||||
Reference in New Issue
Block a user