mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-31 06:23:08 +02:00
A bunch of fixes
This commit is contained in:
@@ -21,8 +21,7 @@ import {
|
||||
import classNames from 'classnames';
|
||||
import { atom, useAtomValue } from 'jotai';
|
||||
import { selectAtom } from 'jotai/utils';
|
||||
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import { useKey } from 'react-use';
|
||||
import { memo, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import { moveToWorkspace } from '../commands/moveToWorkspace';
|
||||
import { openFolderSettings } from '../commands/openFolderSettings';
|
||||
import { activeCookieJarAtom } from '../hooks/useActiveCookieJar';
|
||||
@@ -150,33 +149,31 @@ function Sidebar({ className }: { className?: string }) {
|
||||
await Promise.all(
|
||||
items.map((m, i) =>
|
||||
// Spread item sortPriority out over before/after range
|
||||
patchModel(m, { sortPriority: beforePriority + (i + 1) * increment, folderId }),
|
||||
patchModel(m, {
|
||||
sortPriority: beforePriority + (i + 1) * increment,
|
||||
folderId,
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
op>
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleTreeRefInit = useCallback((n: TreeHandle) => {
|
||||
treeRef.current = n;
|
||||
if (n == null) return;
|
||||
const activeId = jotaiStore.get(activeIdAtom);
|
||||
if (activeId == null) return;
|
||||
const selectedIds = jotaiStore.get(selectedIdsFamily(treeId));
|
||||
if (selectedIds.length > 0) return;
|
||||
n.selectItem(activeId);
|
||||
}, [treeId]);
|
||||
|
||||
// Ensure active id is always selected when it changes
|
||||
useEffect(() => {
|
||||
return jotaiStore.sub(activeIdAtom, () => {
|
||||
const handleTreeRefInit = useCallback(
|
||||
(n: TreeHandle) => {
|
||||
treeRef.current = n;
|
||||
if (n == null) return;
|
||||
const activeId = jotaiStore.get(activeIdAtom);
|
||||
if (activeId == null) return;
|
||||
treeRef.current?.selectItem(activeId);
|
||||
});
|
||||
}, []);
|
||||
const selectedIds = jotaiStore.get(selectedIdsFamily(treeId));
|
||||
if (selectedIds.length > 0) return;
|
||||
n.selectItem(activeId);
|
||||
},
|
||||
[treeId],
|
||||
);
|
||||
|
||||
const clearFilterText = useCallback(() => {
|
||||
jotaiStore.set(sidebarFilterAtom, { text: '', key: `${Math.random()}` });
|
||||
@@ -204,14 +201,6 @@ function Sidebar({ className }: { className?: string }) {
|
||||
[],
|
||||
);
|
||||
|
||||
// Focus the first sidebar item on arrow down from filter
|
||||
useKey('ArrowDown', (e) => {
|
||||
if (e.key === 'ArrowDown' && filterRef.current?.isFocused()) {
|
||||
e.preventDefault();
|
||||
treeRef.current?.focus();
|
||||
}
|
||||
});
|
||||
|
||||
const actions = useMemo(() => {
|
||||
const enable = () => treeRef.current?.hasFocus() ?? false;
|
||||
|
||||
@@ -291,7 +280,11 @@ function Sidebar({ className }: { className?: string }) {
|
||||
|
||||
// No children means we're in the root
|
||||
if (child == null) {
|
||||
return getCreateDropdownItems({ workspaceId, activeRequest: null, folderId: null });
|
||||
return getCreateDropdownItems({
|
||||
workspaceId,
|
||||
activeRequest: null,
|
||||
folderId: null,
|
||||
});
|
||||
}
|
||||
|
||||
const workspaces = jotaiStore.get(workspacesAtom);
|
||||
@@ -355,12 +348,19 @@ function Sidebar({ className }: { className?: string }) {
|
||||
items.length === 1 && child.model === 'folder'
|
||||
? [
|
||||
{ type: 'separator' },
|
||||
...getCreateDropdownItems({ workspaceId, activeRequest: null, folderId: child.id }),
|
||||
...getCreateDropdownItems({
|
||||
workspaceId,
|
||||
activeRequest: null,
|
||||
folderId: child.id,
|
||||
}),
|
||||
]
|
||||
: [];
|
||||
const menuItems: ContextMenuProps['items'] = [
|
||||
...initialItems,
|
||||
{ type: 'separator', hidden: initialItems.filter((v) => !v.hidden).length === 0 },
|
||||
{
|
||||
type: 'separator',
|
||||
hidden: initialItems.filter((v) => !v.hidden).length === 0,
|
||||
},
|
||||
{
|
||||
label: 'Rename',
|
||||
leftSlot: <Icon icon="pencil" />,
|
||||
@@ -421,7 +421,9 @@ function Sidebar({ className }: { className?: string }) {
|
||||
const view = filterRef.current;
|
||||
if (!view) return;
|
||||
const ext = filter({ fields: allFields ?? [] });
|
||||
view.dispatch({ effects: filterLanguageCompartmentRef.current.reconfigure(ext) });
|
||||
view.dispatch({
|
||||
effects: filterLanguageCompartmentRef.current.reconfigure(ext),
|
||||
});
|
||||
}, [allFields]);
|
||||
|
||||
if (tree == null || hidden) {
|
||||
@@ -434,7 +436,7 @@ function Sidebar({ className }: { className?: string }) {
|
||||
aria-hidden={hidden ?? undefined}
|
||||
className={classNames(className, 'h-full grid grid-rows-[auto_minmax(0,1fr)_auto]')}
|
||||
>
|
||||
<div className="px-3 pt-3 grid grid-cols-[1fr_auto] items-center -mr-2.5">
|
||||
<div className="w-full px-3 pt-3 grid grid-cols-[minmax(0,1fr)_auto] items-center -mr-2.5">
|
||||
{(tree.children?.length ?? 0) > 0 && (
|
||||
<>
|
||||
<Input
|
||||
@@ -551,7 +553,10 @@ const allPotentialChildrenAtom = atom<SidebarModel[]>((get) => {
|
||||
|
||||
const memoAllPotentialChildrenAtom = deepEqualAtom(allPotentialChildrenAtom);
|
||||
|
||||
const sidebarFilterAtom = atom<{ text: string; key: string }>({ text: '', key: '' });
|
||||
const sidebarFilterAtom = atom<{ text: string; key: string }>({
|
||||
text: '',
|
||||
key: '',
|
||||
});
|
||||
|
||||
const sidebarTreeAtom = atom<[TreeNode<SidebarModel>, FieldDef[]] | null>((get) => {
|
||||
const allModels = get(memoAllPotentialChildrenAtom);
|
||||
@@ -580,21 +585,24 @@ const sidebarTreeAtom = atom<[TreeNode<SidebarModel>, FieldDef[]] | null>((get)
|
||||
const build = (node: TreeNode<SidebarModel>, depth: number): boolean => {
|
||||
const childItems = childrenMap[node.item.id] ?? [];
|
||||
let matchesSelf = true;
|
||||
const fields = getItemFields(node.item);
|
||||
const fields = getItemFields(node);
|
||||
const model = node.item.model;
|
||||
const isLeafNode = !(model === 'folder' || model === 'workspace');
|
||||
|
||||
for (const [field, value] of Object.entries(fields)) {
|
||||
if (!value) continue;
|
||||
allFields[field] = allFields[field] ?? new Set();
|
||||
allFields[field].add(value);
|
||||
}
|
||||
|
||||
if (queryAst != null) {
|
||||
matchesSelf = evaluate(queryAst, { text: getItemText(node.item), fields });
|
||||
matchesSelf = isLeafNode && evaluate(queryAst, { text: getItemText(node.item), fields });
|
||||
}
|
||||
|
||||
let matchesChild = false;
|
||||
|
||||
// Recurse to children
|
||||
const m = node.item.model;
|
||||
node.children = m === 'folder' || m === 'workspace' ? [] : undefined;
|
||||
node.children = !isLeafNode ? [] : undefined;
|
||||
|
||||
if (node.children != null) {
|
||||
childItems.sort((a, b) => {
|
||||
@@ -623,7 +631,7 @@ const sidebarTreeAtom = atom<[TreeNode<SidebarModel>, FieldDef[]] | null>((get)
|
||||
|
||||
const root: TreeNode<SidebarModel> = {
|
||||
item: activeWorkspace,
|
||||
parent: null,
|
||||
parent: null,
|
||||
children: [],
|
||||
depth: 0,
|
||||
};
|
||||
@@ -633,7 +641,10 @@ const sidebarTreeAtom = atom<[TreeNode<SidebarModel>, FieldDef[]] | null>((get)
|
||||
|
||||
const fields: FieldDef[] = [];
|
||||
for (const [name, values] of Object.entries(allFields)) {
|
||||
fields.push({ name, values: Array.from(values).filter((v) => v.length < 20) });
|
||||
fields.push({
|
||||
name,
|
||||
values: Array.from(values).filter((v) => v.length < 20),
|
||||
});
|
||||
}
|
||||
return [root, fields] as const;
|
||||
});
|
||||
@@ -716,7 +727,9 @@ const SidebarInnerItem = memo(function SidebarInnerItem({
|
||||
);
|
||||
});
|
||||
|
||||
function getItemFields(item: SidebarModel): Record<string, string> {
|
||||
function getItemFields(node: TreeNode<SidebarModel>): Record<string, string> {
|
||||
const item = node.item;
|
||||
|
||||
if (item.model === 'workspace') return {};
|
||||
|
||||
const fields: Record<string, string> = {};
|
||||
@@ -736,9 +749,20 @@ function getItemFields(item: SidebarModel): Record<string, string> {
|
||||
if (item.model === 'grpc_request') fields.type = 'grpc';
|
||||
else if (item.model === 'websocket_request') fields.type = 'ws';
|
||||
|
||||
if (node.parent?.item.model === 'folder') {
|
||||
fields.folder = node.parent.item.name;
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
function getItemText(item: SidebarModel): string {
|
||||
return resolvedModelName(item);
|
||||
const segments = [];
|
||||
if (item.model === 'http_request') {
|
||||
segments.push(item.method);
|
||||
}
|
||||
|
||||
segments.push(resolvedModelName(item));
|
||||
|
||||
return segments.join(' ');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user