优化侧边栏菜单排序的实现

This commit is contained in:
jingrow 2026-03-17 20:43:57 +08:00
parent 785c3bfa9b
commit 4715ca0e87
4 changed files with 11 additions and 35 deletions

View File

@ -25,7 +25,7 @@
<!-- Edit mode: show workspace items with controls --> <!-- Edit mode: show workspace items with controls -->
<div v-else class="edit-menu"> <div v-else class="edit-menu">
<draggable <draggable
v-model="editableWorkspaces" v-model="menuStore.editableWorkspaceOrder"
item-key="id" item-key="id"
> >
<template #item="{ element }"> <template #item="{ element }">
@ -97,7 +97,6 @@ const workspaceEditStore = useWorkspaceEditStore()
const appName = computed(() => localStorage.getItem('appName') || 'Jingrow') const appName = computed(() => localStorage.getItem('appName') || 'Jingrow')
const editableWorkspaces = ref<AppMenuItem[]>([])
const editDialogState = ref({ show: false, workspace: null as AppMenuItem | null }) const editDialogState = ref({ show: false, workspace: null as AppMenuItem | null })
const parentWorkspaceOptions = computed(() => { const parentWorkspaceOptions = computed(() => {
@ -108,7 +107,7 @@ const parentWorkspaceOptions = computed(() => {
const isPrivate = currentWorkspace.isPrivate ?? false const isPrivate = currentWorkspace.isPrivate ?? false
// Filter workspaces: only same type (public/private) and exclude current workspace // Filter workspaces: only same type (public/private) and exclude current workspace
return editableWorkspaces.value return menuStore.editableWorkspaceOrder
.filter(w => { .filter(w => {
// Exclude current workspace itself // Exclude current workspace itself
if (w.id === currentWorkspace.id) return false if (w.id === currentWorkspace.id) return false
@ -129,13 +128,6 @@ watch(() => workspaceEditStore.isEditMode, (isEdit) => {
if (isEdit) syncEditableWorkspaces() if (isEdit) syncEditableWorkspaces()
}) })
// Sync sorted workspaces to store when changed (for save)
watch(editableWorkspaces, (items) => {
if (workspaceEditStore.isEditMode) {
workspaceEditStore.updateSortedWorkspaces(items)
}
}, { deep: true })
function syncEditableWorkspaces() { function syncEditableWorkspaces() {
const workspaceItems = menuStore.items const workspaceItems = menuStore.items
.filter(item => item.type === 'workspace') .filter(item => item.type === 'workspace')
@ -143,11 +135,6 @@ function syncEditableWorkspaces() {
// Sort to ensure parent items come before their children // Sort to ensure parent items come before their children
const sorted: AppMenuItem[] = [] const sorted: AppMenuItem[] = []
const byId: Record<string, AppMenuItem> = {}
workspaceItems.forEach(item => {
byId[item.id] = item
})
// First add all root items (items without parent) // First add all root items (items without parent)
workspaceItems.forEach(item => { workspaceItems.forEach(item => {
@ -162,7 +149,7 @@ function syncEditableWorkspaces() {
} }
}) })
editableWorkspaces.value = sorted menuStore.editableWorkspaceOrder = sorted
} }
function getMenuOptions(workspace: AppMenuItem) { function getMenuOptions(workspace: AppMenuItem) {
@ -189,7 +176,7 @@ async function editWorkspace(workspace: AppMenuItem) {
// Convert parentId (name with user suffix) to parent label (title without suffix) // Convert parentId (name with user suffix) to parent label (title without suffix)
const processedWorkspace = { ...workspace } const processedWorkspace = { ...workspace }
if (processedWorkspace.parentId) { if (processedWorkspace.parentId) {
const parentItem = editableWorkspaces.value.find(w => w.workspaceName === processedWorkspace.parentId) const parentItem = menuStore.editableWorkspaceOrder.find(w => w.workspaceName === processedWorkspace.parentId)
if (parentItem) { if (parentItem) {
processedWorkspace.parentId = parentItem.label processedWorkspace.parentId = parentItem.label
} }

View File

@ -66,6 +66,9 @@ export const useMenuStore = defineStore('menu', () => {
const hasWorkspaceAccess = ref(false) const hasWorkspaceAccess = ref(false)
const hasCreateWorkspaceAccess = ref(false) const hasCreateWorkspaceAccess = ref(false)
// Editable workspace order (for sidebar drag sorting in edit mode)
const editableWorkspaceOrder = ref<AppMenuItem[]>([])
// 正确初始化为数组,而不是函数 // 正确初始化为数组,而不是函数
const initItems = () => { const initItems = () => {
const cached = loadFromStorage() const cached = loadFromStorage()
@ -237,6 +240,7 @@ export const useMenuStore = defineStore('menu', () => {
workspaces, workspaces,
hasWorkspaceAccess, hasWorkspaceAccess,
hasCreateWorkspaceAccess, hasCreateWorkspaceAccess,
editableWorkspaceOrder,
addMenu, addMenu,
updateMenu, updateMenu,
removeMenu, removeMenu,

View File

@ -1,44 +1,29 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref } from 'vue' import { ref } from 'vue'
import type { AppMenuItem } from './menu'
/** /**
* Workspace Edit Mode Store * Workspace Edit Mode Store
* Manages global edit mode state for workspace sidebar * Manages global edit mode state for workspace sidebar
*/ */
export const useWorkspaceEditStore = defineStore('workspaceEdit', () => { export const useWorkspaceEditStore = defineStore('workspaceEdit', () => {
// Edit mode state
const isEditMode = ref(false) const isEditMode = ref(false)
// Sorted workspace items (updated when user drags in sidebar)
const sortedWorkspaces = ref<AppMenuItem[]>([])
// Enter edit mode
function enterEditMode() { function enterEditMode() {
isEditMode.value = true isEditMode.value = true
} }
// Exit edit mode
function exitEditMode() { function exitEditMode() {
isEditMode.value = false isEditMode.value = false
} }
// Toggle edit mode
function toggleEditMode() { function toggleEditMode() {
isEditMode.value = !isEditMode.value isEditMode.value = !isEditMode.value
} }
// Update sorted workspaces
function updateSortedWorkspaces(items: AppMenuItem[]) {
sortedWorkspaces.value = items
}
return { return {
isEditMode, isEditMode,
sortedWorkspaces,
enterEditMode, enterEditMode,
exitEditMode, exitEditMode,
toggleEditMode, toggleEditMode
updateSortedWorkspaces
} }
}) })

View File

@ -966,8 +966,8 @@ async function saveChanges() {
// Save sidebar workspace sort order // Save sidebar workspace sort order
async function saveSidebarSortOrder() { async function saveSidebarSortOrder() {
try { try {
// Use sorted workspaces from store (updated by sidebar drag) // Use sorted workspaces from menuStore (updated by sidebar drag)
const workspaceItems = workspaceEditStore.sortedWorkspaces const workspaceItems = menuStore.editableWorkspaceOrder
if (!workspaceItems || workspaceItems.length === 0) return if (!workspaceItems || workspaceItems.length === 0) return