fix(sidebar): improve pinned item drag ordering
This commit is contained in:
1 parent
4c57520a12
commit
d5e0cde7e2
7 files changed
+476
-32
No files matched your search
@@ -82,9 +82,13 @@ describe("connectionStore pinned tree node removal", () => {
|
||||
|
||||
const usersKey = treeNodePinKey(users);
|
||||
const ordersKey = treeNodePinKey(orders);
|
||||
store.beginPinnedTreeNodeReorder(usersKey);
|
||||
expect(store.reorderPinnedTreeNodes(usersKey, ordersKey, "after")).toBe(true);
|
||||
store.endPinnedTreeNodeReorder();
|
||||
await vi.waitFor(() => expect(savePinnedTreeNodeIds).toHaveBeenCalledTimes(1));
|
||||
store.beginPinnedTreeNodeReorder(ordersKey);
|
||||
expect(store.reorderPinnedTreeNodes(ordersKey, usersKey, "after")).toBe(true);
|
||||
store.endPinnedTreeNodeReorder();
|
||||
|
||||
expect(savePinnedTreeNodeIds).toHaveBeenCalledTimes(1);
|
||||
resolvers[0]!();
|
||||
@@ -97,6 +101,49 @@ describe("connectionStore pinned tree node removal", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("caches active drag targets and invalidates them on tree changes and drag end", async () => {
|
||||
vi.doMock("@/lib/backend/tauriRuntime", () => ({ isTauriRuntime: () => false }));
|
||||
|
||||
const { useConnectionStore } = await import("@/stores/connectionStore");
|
||||
const store = useConnectionStore();
|
||||
const users = tableNode("users");
|
||||
const orders = tableNode("orders");
|
||||
const logs = tableNode("logs");
|
||||
store.treeNodes = [{ id: "conn", label: "Connection", type: "connection", connectionId: "conn", children: [users, orders, logs] }];
|
||||
store.toggleTreeNodePin(users);
|
||||
store.toggleTreeNodePin(orders);
|
||||
store.toggleTreeNodePin(logs);
|
||||
|
||||
const usersKey = treeNodePinKey(users);
|
||||
const ordersKey = treeNodePinKey(orders);
|
||||
const logsKey = treeNodePinKey(logs);
|
||||
let schemaReads = 0;
|
||||
Object.defineProperty(orders, "schema", {
|
||||
configurable: true,
|
||||
get() {
|
||||
schemaReads += 1;
|
||||
return "public";
|
||||
},
|
||||
});
|
||||
|
||||
store.beginPinnedTreeNodeReorder(usersKey);
|
||||
expect(store.isPinnedTreeNodeReorderTarget(ordersKey)).toBe(true);
|
||||
const readsAfterFirstLookup = schemaReads;
|
||||
expect(readsAfterFirstLookup).toBeGreaterThan(0);
|
||||
|
||||
for (let index = 0; index < 100; index += 1) {
|
||||
expect(store.isPinnedTreeNodeReorderTarget(index % 2 === 0 ? ordersKey : logsKey)).toBe(true);
|
||||
}
|
||||
expect(schemaReads).toBe(readsAfterFirstLookup);
|
||||
|
||||
store.treeNodes[0].children = [users, logs];
|
||||
store.treeNodes.push({ id: "other", label: "Other", type: "connection", connectionId: "other", children: [orders] });
|
||||
expect(store.isPinnedTreeNodeReorderTarget(ordersKey)).toBe(false);
|
||||
|
||||
store.endPinnedTreeNodeReorder();
|
||||
expect(store.isPinnedTreeNodeReorderTarget(logsKey)).toBe(false);
|
||||
});
|
||||
|
||||
it("moves a renamed pinned object to its new identity so recreating the old name is unpinned", async () => {
|
||||
vi.doMock("@/lib/backend/tauriRuntime", () => ({ isTauriRuntime: () => false }));
|
||||
|
||||
|
||||
@@ -319,6 +319,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
const sidebarTableStorageInFlight = new Map<string, Promise<ObjectStatistics[]>>();
|
||||
const pinnedTreeNodeOrder = ref<string[]>([]);
|
||||
const pinnedTreeNodeIds = ref<Set<string>>(new Set());
|
||||
const activePinnedTreeNodeReorderKey = ref<string | null>(null);
|
||||
let pinnedTreeNodePersistQueue: Promise<void> = Promise.resolve();
|
||||
const connectedIds = ref<Set<string>>(new Set());
|
||||
const identifierQuotes = ref<Record<string, string>>({});
|
||||
@@ -1922,13 +1923,40 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
function collectPinnedTreeNodeReorderTargets(draggedKey: string): Set<string> {
|
||||
const dragged = findPinnedTreeNodeLocation(treeNodes.value, draggedKey);
|
||||
if (!dragged || !isTreeNodePinned(dragged.node) || isFixedPriorityTreeNode(dragged.node)) return new Set();
|
||||
|
||||
const targets = new Set<string>();
|
||||
for (const sibling of dragged.siblings) {
|
||||
const siblingKey = treeNodePinKey(sibling);
|
||||
if (siblingKey === draggedKey || !isTreeNodePinned(sibling) || isFixedPriorityTreeNode(sibling)) continue;
|
||||
targets.add(siblingKey);
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
const activePinnedTreeNodeReorderTargets = computed(() => {
|
||||
const draggedKey = activePinnedTreeNodeReorderKey.value;
|
||||
return draggedKey ? collectPinnedTreeNodeReorderTargets(draggedKey) : new Set<string>();
|
||||
});
|
||||
|
||||
function beginPinnedTreeNodeReorder(draggedKey: string) {
|
||||
activePinnedTreeNodeReorderKey.value = draggedKey || null;
|
||||
}
|
||||
|
||||
function endPinnedTreeNodeReorder() {
|
||||
activePinnedTreeNodeReorderKey.value = null;
|
||||
}
|
||||
|
||||
function isPinnedTreeNodeReorderTarget(targetKey: string): boolean {
|
||||
return !!targetKey && targetKey !== activePinnedTreeNodeReorderKey.value && activePinnedTreeNodeReorderTargets.value.has(targetKey);
|
||||
}
|
||||
|
||||
function canReorderPinnedTreeNodes(draggedKey: string, targetKey: string): boolean {
|
||||
if (!draggedKey || !targetKey || draggedKey === targetKey) return false;
|
||||
const dragged = findPinnedTreeNodeLocation(treeNodes.value, draggedKey);
|
||||
const target = findPinnedTreeNodeLocation(treeNodes.value, targetKey);
|
||||
if (!dragged || !target || dragged.siblings !== target.siblings) return false;
|
||||
if (!isTreeNodePinned(dragged.node) || !isTreeNodePinned(target.node)) return false;
|
||||
return !isFixedPriorityTreeNode(dragged.node) && !isFixedPriorityTreeNode(target.node);
|
||||
if (activePinnedTreeNodeReorderKey.value === draggedKey) return activePinnedTreeNodeReorderTargets.value.has(targetKey);
|
||||
return collectPinnedTreeNodeReorderTargets(draggedKey).has(targetKey);
|
||||
}
|
||||
|
||||
function reorderPinnedTreeNodes(draggedKey: string, targetKey: string, position: DropPosition): boolean {
|
||||
@@ -6089,6 +6117,9 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
isTreeNodePinned,
|
||||
orderByPinnedTreeNodes,
|
||||
toggleTreeNodePin,
|
||||
beginPinnedTreeNodeReorder,
|
||||
endPinnedTreeNodeReorder,
|
||||
isPinnedTreeNodeReorderTarget,
|
||||
canReorderPinnedTreeNodes,
|
||||
reorderPinnedTreeNodes,
|
||||
addConnection,
|
||||
|
||||
Reference in new issue
Block a user