mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-11 17:46:41 -05:00
Show full paths in command palette switcher
https://feedback.yaak.app/p/command-palette-search-should-include-parent-folder-names
This commit is contained in:
@@ -30,7 +30,10 @@ import { deleteModelWithConfirm } from '../lib/deleteModelWithConfirm';
|
||||
import { showDialog } from '../lib/dialog';
|
||||
import { editEnvironment } from '../lib/editEnvironment';
|
||||
import { renameModelWithPrompt } from '../lib/renameModelWithPrompt';
|
||||
import { resolvedModelNameWithFolders } from '../lib/resolvedModelName';
|
||||
import {
|
||||
resolvedModelNameWithFolders,
|
||||
resolvedModelNameWithFoldersArray,
|
||||
} from '../lib/resolvedModelName';
|
||||
import { router } from '../lib/router';
|
||||
import { setWorkspaceSearchParams } from '../lib/setWorkspaceSearchParams';
|
||||
import { CookieDialog } from './CookieDialog';
|
||||
@@ -40,7 +43,6 @@ import { HotKey } from './core/HotKey';
|
||||
import { HttpMethodTag } from './core/HttpMethodTag';
|
||||
import { Icon } from './core/Icon';
|
||||
import { PlainInput } from './core/PlainInput';
|
||||
import { HStack } from './core/Stacks';
|
||||
|
||||
interface CommandPaletteGroup {
|
||||
key: string;
|
||||
@@ -275,10 +277,17 @@ export function CommandPaletteDialog({ onClose }: { onClose: () => void }) {
|
||||
key: `switch-request-${r.id}`,
|
||||
searchText: resolvedModelNameWithFolders(r),
|
||||
label: (
|
||||
<HStack space={2}>
|
||||
<HttpMethodTag short className="text-xs" request={r} />
|
||||
<div className="truncate">{resolvedModelNameWithFolders(r)}</div>
|
||||
</HStack>
|
||||
<div className="flex items-center gap-x-0.5">
|
||||
<HttpMethodTag short className="text-xs mr-2" request={r} />
|
||||
{resolvedModelNameWithFoldersArray(r).map((name, i, all) => (
|
||||
<>
|
||||
{i !== 0 && (
|
||||
<Icon icon="chevron_right" className="opacity-80"/>
|
||||
)}
|
||||
<div className={classNames(i < all.length - 1 && 'truncate')}>{name}</div>
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
),
|
||||
onSelect: async () => {
|
||||
await router.navigate({
|
||||
@@ -400,7 +409,7 @@ export function CommandPaletteDialog({ onClose }: { onClose: () => void }) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="h-full w-[400px] grid grid-rows-[auto_minmax(0,1fr)] overflow-hidden py-2">
|
||||
<div className="h-full w-[min(700px,80vw)] grid grid-rows-[auto_minmax(0,1fr)] overflow-hidden py-2">
|
||||
<div className="px-2 w-full">
|
||||
<PlainInput
|
||||
autoFocus
|
||||
|
||||
@@ -52,7 +52,13 @@ export function Overlay({
|
||||
{open && (
|
||||
<FocusTrap
|
||||
focusTrapOptions={{
|
||||
allowOutsideClick: true, // So we can still click toasts and things
|
||||
// Allow outside click so we can click things like toasts
|
||||
allowOutsideClick: true,
|
||||
delayInitialFocus: true,
|
||||
checkCanFocusTrap: async () => {
|
||||
// Not sure why delayInitialFocus: true doesn't help, but having this no-op promise
|
||||
// seems to be required to make things work.
|
||||
},
|
||||
}}
|
||||
>
|
||||
<m.div
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from 'react';
|
||||
import { useRandomKey } from '../../hooks/useRandomKey';
|
||||
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
|
||||
import { generateId } from '../../lib/generateId';
|
||||
import { IconButton } from './IconButton';
|
||||
import type { InputProps } from './Input';
|
||||
import { Label } from './Label';
|
||||
@@ -99,7 +100,7 @@ export const PlainInput = forwardRef<{ focus: () => void }, PlainInputProps>(fun
|
||||
}
|
||||
}, [regenerateFocusedUpdateKey, defaultValue]);
|
||||
|
||||
const id = `input-${name}`;
|
||||
const id = useRef(`input-${generateId()}`);
|
||||
const commonClassName = classNames(
|
||||
className,
|
||||
'!bg-transparent min-w-0 w-full focus:outline-none placeholder:text-placeholder',
|
||||
@@ -134,7 +135,7 @@ export const PlainInput = forwardRef<{ focus: () => void }, PlainInputProps>(fun
|
||||
)}
|
||||
>
|
||||
<Label
|
||||
htmlFor={id}
|
||||
htmlFor={id.current}
|
||||
className={labelClassName}
|
||||
visuallyHidden={hideLabel}
|
||||
required={required}
|
||||
@@ -177,10 +178,11 @@ export const PlainInput = forwardRef<{ focus: () => void }, PlainInputProps>(fun
|
||||
)}
|
||||
>
|
||||
<input
|
||||
id={id}
|
||||
id={id.current}
|
||||
ref={inputRef}
|
||||
key={forceUpdateKey}
|
||||
type={type === 'password' && !obscured ? 'text' : type}
|
||||
name={name}
|
||||
defaultValue={defaultValue ?? undefined}
|
||||
autoComplete="off"
|
||||
autoCapitalize="off"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { AnyModel} from '@yaakapp-internal/models';
|
||||
import type { AnyModel } from '@yaakapp-internal/models';
|
||||
import { foldersAtom } from '@yaakapp-internal/models';
|
||||
import { jotaiStore } from './jotai';
|
||||
|
||||
@@ -39,7 +39,11 @@ export function resolvedModelName(r: AnyModel | null): string {
|
||||
}
|
||||
|
||||
export function resolvedModelNameWithFolders(model: AnyModel | null): string {
|
||||
if (model == null) return '';
|
||||
return resolvedModelNameWithFoldersArray(model).join(' / ');
|
||||
}
|
||||
|
||||
export function resolvedModelNameWithFoldersArray(model: AnyModel | null): string[] {
|
||||
if (model == null) return [];
|
||||
const folders = jotaiStore.get(foldersAtom) ?? [];
|
||||
|
||||
const getParents = (m: AnyModel, names: string[]) => {
|
||||
@@ -47,11 +51,11 @@ export function resolvedModelNameWithFolders(model: AnyModel | null): string {
|
||||
if ('folderId' in m) {
|
||||
const parent = folders.find((f) => f.id === m.folderId);
|
||||
if (parent) {
|
||||
names = [resolvedModelName(parent), ...names];
|
||||
names = [...resolvedModelNameWithFoldersArray(parent), ...names];
|
||||
}
|
||||
}
|
||||
return names;
|
||||
};
|
||||
|
||||
return getParents(model, []).join(' / ');
|
||||
return getParents(model, []);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user