mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-21 08:21:19 +02:00
Websocket Support (#159)
This commit is contained in:
118
src-web/components/sidebar/SidebarAtoms.ts
Normal file
118
src-web/components/sidebar/SidebarAtoms.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import type { Folder, GrpcRequest, HttpRequest, WebsocketRequest } from '@yaakapp-internal/models';
|
||||
|
||||
// This is an atom so we can use it in the child items to avoid re-rendering the entire list
|
||||
import { atom } from 'jotai';
|
||||
import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace';
|
||||
import { foldersAtom } from '../../hooks/useFolders';
|
||||
import { requestsAtom } from '../../hooks/useRequests';
|
||||
import { deepEqualAtom } from '../../lib/atoms';
|
||||
import { fallbackRequestName } from '../../lib/fallbackRequestName';
|
||||
import type { SidebarTreeNode } from './Sidebar';
|
||||
|
||||
export const sidebarSelectedIdAtom = atom<string | null>(null);
|
||||
|
||||
const allPotentialChildrenAtom = atom((get) => {
|
||||
const requests = get(requestsAtom);
|
||||
const folders = get(foldersAtom);
|
||||
return [...requests, ...folders].map((v) => ({
|
||||
id: v.id,
|
||||
model: v.model,
|
||||
folderId: v.folderId,
|
||||
name: fallbackRequestName(v),
|
||||
workspaceId: v.workspaceId,
|
||||
sortPriority: v.sortPriority,
|
||||
}));
|
||||
});
|
||||
|
||||
const memoAllPotentialChildrenAtom = deepEqualAtom(allPotentialChildrenAtom);
|
||||
|
||||
export const sidebarTreeAtom = atom<{
|
||||
tree: SidebarTreeNode | null;
|
||||
treeParentMap: Record<string, SidebarTreeNode>;
|
||||
selectableRequests: {
|
||||
id: string;
|
||||
index: number;
|
||||
tree: SidebarTreeNode;
|
||||
}[];
|
||||
}>((get) => {
|
||||
const allModels = get(memoAllPotentialChildrenAtom);
|
||||
const activeWorkspace = get(activeWorkspaceAtom);
|
||||
|
||||
const childrenMap: Record<string, typeof allModels> = {};
|
||||
for (const item of allModels) {
|
||||
if ('folderId' in item && item.folderId == null) {
|
||||
childrenMap[item.workspaceId] = childrenMap[item.workspaceId] ?? [];
|
||||
childrenMap[item.workspaceId]!.push(item);
|
||||
} else if ('folderId' in item && item.folderId != null) {
|
||||
childrenMap[item.folderId] = childrenMap[item.folderId] ?? [];
|
||||
childrenMap[item.folderId]!.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
const treeParentMap: Record<string, SidebarTreeNode> = {};
|
||||
const selectableRequests: {
|
||||
id: string;
|
||||
index: number;
|
||||
tree: SidebarTreeNode;
|
||||
}[] = [];
|
||||
|
||||
if (activeWorkspace == null) {
|
||||
return { tree: null, treeParentMap, selectableRequests };
|
||||
}
|
||||
|
||||
const selectedRequest: HttpRequest | GrpcRequest | WebsocketRequest | null = null;
|
||||
let selectableRequestIndex = 0;
|
||||
|
||||
// Put requests and folders into a tree structure
|
||||
const next = (node: SidebarTreeNode): SidebarTreeNode => {
|
||||
const childItems = childrenMap[node.id] ?? [];
|
||||
|
||||
// Recurse to children
|
||||
const depth = node.depth + 1;
|
||||
childItems.sort((a, b) => a.sortPriority - b.sortPriority);
|
||||
for (const childItem of childItems) {
|
||||
treeParentMap[childItem.id] = node;
|
||||
// Add to children
|
||||
node.children.push(next(itemFromModel(childItem, depth)));
|
||||
// Add to selectable requests
|
||||
if (childItem.model !== 'folder') {
|
||||
selectableRequests.push({
|
||||
id: childItem.id,
|
||||
index: selectableRequestIndex++,
|
||||
tree: node,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
const tree = next({
|
||||
id: activeWorkspace.id,
|
||||
name: activeWorkspace.name,
|
||||
model: activeWorkspace.model,
|
||||
children: [],
|
||||
depth: 0,
|
||||
});
|
||||
|
||||
return { tree, treeParentMap, selectableRequests, selectedRequest };
|
||||
});
|
||||
|
||||
function itemFromModel(
|
||||
item: Pick<
|
||||
Folder | HttpRequest | GrpcRequest | WebsocketRequest,
|
||||
'folderId' | 'model' | 'workspaceId' | 'id' | 'name' | 'sortPriority'
|
||||
>,
|
||||
depth = 0,
|
||||
): SidebarTreeNode {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
model: item.model,
|
||||
sortPriority: 'sortPriority' in item ? item.sortPriority : -1,
|
||||
workspaceId: item.workspaceId,
|
||||
folderId: item.folderId,
|
||||
depth,
|
||||
children: [],
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user