fix(phase-4): add Move to folder dropdown on DocumentCard hover
This commit is contained in:
@@ -33,17 +33,51 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Share button (hover-reveal) -->
|
<!-- Action buttons (hover-reveal) -->
|
||||||
<button
|
<div class="opacity-0 group-hover:opacity-100 transition-opacity flex items-center gap-1 shrink-0">
|
||||||
@click.stop="openShareModal"
|
<!-- Move to folder -->
|
||||||
aria-label="Share document"
|
<div class="relative">
|
||||||
class="opacity-0 group-hover:opacity-100 transition-opacity min-h-[44px] min-w-[44px] flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-indigo-600 hover:bg-indigo-50 transition-colors shrink-0"
|
<button
|
||||||
>
|
@click.stop="toggleFolderPicker"
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
aria-label="Move to folder"
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
class="min-h-[44px] min-w-[44px] flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-indigo-600 hover:bg-indigo-50 transition-colors"
|
||||||
d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" />
|
>
|
||||||
</svg>
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
</button>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M3 7a2 2 0 012-2h4l2 2h8a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2V7z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<!-- Folder picker dropdown -->
|
||||||
|
<div
|
||||||
|
v-if="showFolderPicker"
|
||||||
|
class="absolute right-0 top-full mt-1 w-48 bg-white border border-gray-200 rounded-xl shadow-lg z-20 py-1"
|
||||||
|
@click.stop
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="w-full text-left px-3 py-2 text-sm text-gray-600 hover:bg-gray-50"
|
||||||
|
@click.stop="moveToFolder(null)"
|
||||||
|
>Root (no folder)</button>
|
||||||
|
<button
|
||||||
|
v-for="folder in allFolders"
|
||||||
|
:key="folder.id"
|
||||||
|
class="w-full text-left px-3 py-2 text-sm text-gray-700 hover:bg-indigo-50 hover:text-indigo-600 truncate"
|
||||||
|
@click.stop="moveToFolder(folder.id)"
|
||||||
|
>{{ folder.name }}</button>
|
||||||
|
<p v-if="!allFolders.length" class="px-3 py-2 text-xs text-gray-400">No folders yet</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Share -->
|
||||||
|
<button
|
||||||
|
@click.stop="openShareModal"
|
||||||
|
aria-label="Share document"
|
||||||
|
class="min-h-[44px] min-w-[44px] flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-indigo-600 hover:bg-indigo-50 transition-colors"
|
||||||
|
>
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ShareModal -->
|
<!-- ShareModal -->
|
||||||
@@ -56,8 +90,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||||
import { useTopicsStore } from '../../stores/topics.js'
|
import { useTopicsStore } from '../../stores/topics.js'
|
||||||
|
import { useFoldersStore } from '../../stores/folders.js'
|
||||||
|
import { moveDocument } from '../../api/client.js'
|
||||||
import TopicBadge from '../topics/TopicBadge.vue'
|
import TopicBadge from '../topics/TopicBadge.vue'
|
||||||
import ShareModal from '../sharing/ShareModal.vue'
|
import ShareModal from '../sharing/ShareModal.vue'
|
||||||
|
|
||||||
@@ -66,12 +102,36 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const topicsStore = useTopicsStore()
|
const topicsStore = useTopicsStore()
|
||||||
|
const foldersStore = useFoldersStore()
|
||||||
const showShareModal = ref(false)
|
const showShareModal = ref(false)
|
||||||
|
const showFolderPicker = ref(false)
|
||||||
|
|
||||||
|
const allFolders = computed(() => foldersStore.folders)
|
||||||
|
|
||||||
function openShareModal() {
|
function openShareModal() {
|
||||||
showShareModal.value = true
|
showShareModal.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleFolderPicker() {
|
||||||
|
showFolderPicker.value = !showFolderPicker.value
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeFolderPicker(e) {
|
||||||
|
showFolderPicker.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => document.addEventListener('click', closeFolderPicker))
|
||||||
|
onUnmounted(() => document.removeEventListener('click', closeFolderPicker))
|
||||||
|
|
||||||
|
async function moveToFolder(folderId) {
|
||||||
|
showFolderPicker.value = false
|
||||||
|
try {
|
||||||
|
await moveDocument(props.doc.id, folderId)
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Move failed:', e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function topicColor(name) {
|
function topicColor(name) {
|
||||||
return topicsStore.topics.find(t => t.name === name)?.color ?? '#6366f1'
|
return topicsStore.topics.find(t => t.name === name)?.color ?? '#6366f1'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user