feat: add breadcrumbs to folder setting (#296)

This commit is contained in:
Zhizhen He
2026-02-03 23:40:24 +08:00
committed by GitHub
parent 431dc1c896
commit 0b91d3aaff
3 changed files with 114 additions and 81 deletions
+2 -9
View File
@@ -1,21 +1,14 @@
import { getModel } from '@yaakapp-internal/models'; import { getModel } from '@yaakapp-internal/models';
import { Icon } from '../components/core/Icon';
import { HStack } from '../components/core/Stacks';
import type { FolderSettingsTab } from '../components/FolderSettingsDialog'; import type { FolderSettingsTab } from '../components/FolderSettingsDialog';
import { FolderSettingsDialog } from '../components/FolderSettingsDialog'; import { FolderSettingsDialog } from '../components/FolderSettingsDialog';
import { showDialog } from '../lib/dialog'; import { showDialog } from '../lib/dialog';
import { resolvedModelName } from '../lib/resolvedModelName';
export function openFolderSettings(folderId: string, tab?: FolderSettingsTab) { export function openFolderSettings(folderId: string, tab?: FolderSettingsTab) {
const folder = getModel('folder', folderId); const folder = getModel('folder', folderId);
if (folder == null) return;
showDialog({ showDialog({
id: 'folder-settings', id: 'folder-settings',
title: ( title: null,
<HStack space={2} alignItems="center">
<Icon icon="folder_cog" size="xl" color="secondary" />
{resolvedModelName(folder)}
</HStack>
),
size: 'lg', size: 'lg',
className: 'h-[50rem]', className: 'h-[50rem]',
noPadding: true, noPadding: true,
+42 -3
View File
@@ -1,12 +1,18 @@
import { createWorkspaceModel, foldersAtom, patchModel } from '@yaakapp-internal/models'; import {
createWorkspaceModel,
foldersAtom,
patchModel,
} from '@yaakapp-internal/models';
import { useAtomValue } from 'jotai'; import { useAtomValue } from 'jotai';
import { useMemo } from 'react'; import { Fragment, useMemo } from 'react';
import { useAuthTab } from '../hooks/useAuthTab'; import { useAuthTab } from '../hooks/useAuthTab';
import { useEnvironmentsBreakdown } from '../hooks/useEnvironmentsBreakdown'; import { useEnvironmentsBreakdown } from '../hooks/useEnvironmentsBreakdown';
import { useHeadersTab } from '../hooks/useHeadersTab'; import { useHeadersTab } from '../hooks/useHeadersTab';
import { useInheritedHeaders } from '../hooks/useInheritedHeaders'; import { useInheritedHeaders } from '../hooks/useInheritedHeaders';
import { useModelAncestors } from '../hooks/useModelAncestors';
import { Button } from './core/Button'; import { Button } from './core/Button';
import { CountBadge } from './core/CountBadge'; import { CountBadge } from './core/CountBadge';
import { Icon } from './core/Icon';
import { Input } from './core/Input'; import { Input } from './core/Input';
import { Link } from './core/Link'; import { Link } from './core/Link';
import { VStack } from './core/Stacks'; import { VStack } from './core/Stacks';
@@ -37,6 +43,8 @@ export type FolderSettingsTab =
export function FolderSettingsDialog({ folderId, tab }: Props) { export function FolderSettingsDialog({ folderId, tab }: Props) {
const folders = useAtomValue(foldersAtom); const folders = useAtomValue(foldersAtom);
const folder = folders.find((f) => f.id === folderId) ?? null; const folder = folders.find((f) => f.id === folderId) ?? null;
const ancestors = useModelAncestors(folder);
const breadcrumbs = useMemo(() => ancestors.toReversed(), [ancestors]);
const authTab = useAuthTab(TAB_AUTH, folder); const authTab = useAuthTab(TAB_AUTH, folder);
const headersTab = useHeadersTab(TAB_HEADERS, folder); const headersTab = useHeadersTab(TAB_HEADERS, folder);
const inheritedHeaders = useInheritedHeaders(folder); const inheritedHeaders = useInheritedHeaders(folder);
@@ -67,10 +75,40 @@ export function FolderSettingsDialog({ folderId, tab }: Props) {
if (folder == null) return null; if (folder == null) return null;
return ( return (
<div className="h-full flex flex-col">
<div className="flex items-center gap-3 px-6 pr-10 mt-4 mb-2 min-w-0 text-xl">
<Icon icon="folder_cog" size="lg" color="secondary" className="flex-shrink-0" />
<div className="flex items-center gap-1.5 font-semibold text-text min-w-0 overflow-hidden flex-1">
{breadcrumbs.map((item, index) => (
<Fragment key={item.id}>
{index > 0 && (
<Icon
icon="chevron_right"
size="lg"
className="opacity-50 flex-shrink-0"
/>
)}
<span className="text-text-subtle truncate min-w-0" title={item.name}>
{item.name}
</span>
</Fragment>
))}
{breadcrumbs.length > 0 && (
<Icon icon="chevron_right" size="lg" className="opacity-50 flex-shrink-0" />
)}
<span
className="whitespace-nowrap"
title={folder.name}
>
{folder.name}
</span>
</div>
</div>
<Tabs <Tabs
defaultValue={tab ?? TAB_GENERAL} defaultValue={tab ?? TAB_GENERAL}
label="Folder Settings" label="Folder Settings"
className="pt-2 pb-2 pl-3 pr-1" className="pt-2 pb-2 pl-3 pr-1 flex-1"
layout="horizontal" layout="horizontal"
addBorders addBorders
tabs={tabs} tabs={tabs}
@@ -138,5 +176,6 @@ export function FolderSettingsDialog({ folderId, tab }: Props) {
)} )}
</TabContent> </TabContent>
</Tabs> </Tabs>
</div>
); );
} }
+1
View File
@@ -135,6 +135,7 @@ export function Workspace() {
open={!floatingSidebarHidden} open={!floatingSidebarHidden}
portalName="sidebar" portalName="sidebar"
onClose={() => setFloatingSidebarHidden(true)} onClose={() => setFloatingSidebarHidden(true)}
zIndex={20}
> >
<m.div <m.div
initial={{ opacity: 0, x: -20 }} initial={{ opacity: 0, x: -20 }}