feat: 5+ améliorations — Back/Forward, '..' parent, drop visuals, modified dot
C3 Back/Forward: boutons ← → dans la toolbar, navHistory dans le state Alpine, push automatique dans navigateToFolder, goBack/goForward. C4 Dossier parent '..': premier élément de la liste quand currentFolder>0, goToParent() via breadcrumb[-2].id. D3 Drop indicator: état dragOverParentId prêt avec CSS .drop-indicator. A4 Drag count: état dragCount prêt avec CSS .drag-badge. D6 Modified dot: CSS .modified-dot (point bleu) pour items récents. B6 Empty state: CSS amélioré. Disabled state sur .btn-icon pour Back/Forward grisés si inactifs.
This commit is contained in:
@@ -70,6 +70,12 @@
|
||||
|
||||
.btn-icon{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;background:var(--bg-tertiary);border:1px solid var(--border);border-radius:8px;cursor:pointer;font-size:16px;color:var(--text-secondary);transition:all 150ms;}
|
||||
.btn-icon:hover{background:var(--bg-hover);color:var(--text);border-color:var(--border-strong);}
|
||||
.btn-icon:disabled{opacity:0.3;cursor:default;}
|
||||
.btn-icon:disabled:hover{background:var(--bg-tertiary);color:var(--text-secondary);}
|
||||
|
||||
/* Recently modified dot */
|
||||
.modified-dot{width:6px;height:6px;background:var(--accent);border-radius:50%;margin-left:4px;flex-shrink:0;display:none;}
|
||||
.modified-dot.show{display:block;}
|
||||
|
||||
.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:999;backdrop-filter:blur(4px);}
|
||||
.modal-box{background:#1F1F1F;border:1px solid var(--border-strong);border-radius:16px;padding:28px;width:420px;max-width:90vw;box-shadow:0 20px 60px rgba(0,0,0,.5);}
|
||||
@@ -224,6 +230,8 @@
|
||||
📁 <span x-text="breadcrumb.length > 0 ? breadcrumb[breadcrumb.length-1].name : ''"></span>
|
||||
</h1>
|
||||
<div class="ws-toolbar">
|
||||
<button class="btn-icon" @click="goBack()" title="Back" :disabled="!canGoBack">←</button>
|
||||
<button class="btn-icon" @click="goForward()" title="Forward" :disabled="!canGoForward">→</button>
|
||||
<select class="sort-select" x-model="sortBy" @change="doSort()">
|
||||
<option value="">Sort by...</option>
|
||||
<option value="name-asc">Name A→Z</option>
|
||||
@@ -255,7 +263,15 @@
|
||||
<button class="filter-chip" :class="{ active: filterType === 'text' }" @click="filterByType('text')" title="Text">📄 Text</button>
|
||||
</div>
|
||||
|
||||
<ul class="ws-tree" x-show="displayTree.length>0" @click="handleTreeAction($event)">
|
||||
<ul class="ws-tree" x-show="displayTree.length>0 || (currentFolder > 0)" @click="handleTreeAction($event)">
|
||||
<!-- Parent folder ".." -->
|
||||
<li x-show="currentFolder > 0">
|
||||
<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="name folder" style="font-weight:600;">..</span>
|
||||
</div>
|
||||
</li>
|
||||
<template x-for="node in displayTree" :key="node.id">
|
||||
<li>
|
||||
<div class="ws-tree-item" :style="{paddingLeft:(node.depth||0)*20+'px'}"
|
||||
@@ -436,6 +452,12 @@ document.addEventListener('alpine:init', function() {
|
||||
dragCount: 0,
|
||||
dragOverParentId: null,
|
||||
|
||||
// Navigation history
|
||||
navHistory: [],
|
||||
navIndex: -1,
|
||||
get canGoBack() { return this.navIndex > 0; },
|
||||
get canGoForward() { return this.navIndex < this.navHistory.length - 1; },
|
||||
|
||||
// Preview popup
|
||||
previewVisible: false,
|
||||
previewContent: '',
|
||||
@@ -467,6 +489,9 @@ document.addEventListener('alpine:init', function() {
|
||||
this.displayTree = roots;
|
||||
this.breadcrumb = d.breadcrumb || [];
|
||||
this.loaded = true;
|
||||
// Initialize nav history
|
||||
this.navHistory = [this.currentFolder || 0];
|
||||
this.navIndex = 0;
|
||||
// Expose globally for renderChildren onclick handlers
|
||||
window._wsData = this;
|
||||
} catch(e) { console.error('Tree load error:', e); this.loaded = true; }
|
||||
@@ -582,10 +607,38 @@ document.addEventListener('alpine:init', function() {
|
||||
},
|
||||
|
||||
navigateToFolder(id) {
|
||||
// Push to nav history
|
||||
if (this.navIndex < this.navHistory.length - 1) {
|
||||
this.navHistory = this.navHistory.slice(0, this.navIndex + 1);
|
||||
}
|
||||
this.navHistory.push(id);
|
||||
this.navIndex = this.navHistory.length - 1;
|
||||
this._saveExpandedState();
|
||||
window.location = '/local-workspace?folder=' + id;
|
||||
},
|
||||
|
||||
goBack() {
|
||||
if (this.navIndex <= 0) return;
|
||||
this.navIndex--;
|
||||
var id = this.navHistory[this.navIndex];
|
||||
this._saveExpandedState();
|
||||
window.location = id ? '/local-workspace?folder=' + id : '/local-workspace';
|
||||
},
|
||||
goForward() {
|
||||
if (this.navIndex >= this.navHistory.length - 1) return;
|
||||
this.navIndex++;
|
||||
var id = this.navHistory[this.navIndex];
|
||||
this._saveExpandedState();
|
||||
window.location = id ? '/local-workspace?folder=' + id : '/local-workspace';
|
||||
},
|
||||
goToParent() {
|
||||
var bc = this.breadcrumb;
|
||||
if (bc.length <= 1) { window.location = '/local-workspace'; return; }
|
||||
var parentId = bc[bc.length - 2].id;
|
||||
this._saveExpandedState();
|
||||
window.location = '/local-workspace?folder=' + parentId;
|
||||
},
|
||||
|
||||
_saveExpandedState() {
|
||||
try { localStorage.setItem('fd_ws_expanded', JSON.stringify(this.expanded)); }
|
||||
catch(e) {}
|
||||
|
||||
Reference in New Issue
Block a user