Skip to content

Commit 7fd67fe

Browse files
committed
refactor: update DashboardHeader to improve renaming functionality and UI responsiveness
1 parent 83f1f7d commit 7fd67fe

File tree

2 files changed

+62
-51
lines changed

2 files changed

+62
-51
lines changed

apps/nextjs-app/src/features/app/blocks/base/base-side-bar/BaseNodeTree.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ export const BaseNodeTree = () => {
280280
</div>
281281
</BaseNodeAddResourceButton>
282282
</div>
283-
<ScrollArea className="flex w-full" scrollBar="none">
283+
<ScrollArea className="flex w-full !border-none" scrollBar="none">
284284
<Tree indent={INDENTATION_WIDTH} tree={tree}>
285285
<AssistiveTreeDescription tree={tree} />
286286
{tree.getItems().map((item) => {

apps/nextjs-app/src/features/app/dashboard/DashboardHeader.tsx

Lines changed: 61 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { ReactQueryKeys } from '@teable/sdk/config';
1010
import { useBaseId, useBasePermission } from '@teable/sdk/hooks';
1111
import {
1212
Button,
13-
cn,
1413
DropdownMenu,
1514
DropdownMenuContent,
1615
DropdownMenuItem,
@@ -22,20 +21,20 @@ import { toast } from '@teable/ui-lib/shadcn/ui/sonner';
2221
import Head from 'next/head';
2322
import { useRouter } from 'next/router';
2423
import { useTranslation } from 'next-i18next';
25-
import { useRef, useState } from 'react';
24+
import { useEffect, useRef, useState } from 'react';
2625
import { dashboardConfig } from '@/features/i18n/dashboard.config';
2726
import { MenuDeleteItem } from '../components/MenuDeleteItem';
2827
import { useBrand } from '../hooks/useBrand';
2928
import { AddPluginDialog } from './components/AddPluginDialog';
30-
import { DashboardSwitcher } from './components/DashboardSwitcher';
3129

3230
export const DashboardHeader = (props: { dashboardId: string }) => {
3331
const { dashboardId } = props;
3432
const baseId = useBaseId()!;
3533
const router = useRouter();
3634
const queryClient = useQueryClient();
3735
const [menuOpen, setMenuOpen] = useState(false);
38-
const [rename, setRename] = useState<string | null>(null);
36+
const [isRenaming, setIsRenaming] = useState(false);
37+
const [editName, setEditName] = useState<string>('');
3938
const renameRef = useRef<HTMLInputElement>(null);
4039
const { t } = useTranslation(dashboardConfig.i18nNamespaces);
4140
const basePermissions = useBasePermission();
@@ -71,60 +70,77 @@ export const DashboardHeader = (props: { dashboardId: string }) => {
7170
});
7271

7372
const { mutate: renameDashboardMutate } = useMutation({
74-
mutationFn: () => renameDashboard(baseId, dashboardId, rename!),
73+
mutationFn: ({ name }: { name: string }) => renameDashboard(baseId, dashboardId, name),
7574
onSuccess: () => {
76-
setRename(null);
75+
setIsRenaming(false);
7776
queryClient.invalidateQueries(ReactQueryKeys.getDashboardList(baseId));
7877
},
7978
});
8079

8180
const selectedDashboard = dashboardList?.find(({ id }) => id === dashboardId);
81+
const dashboardName = selectedDashboard?.name ?? t('common:noun.dashboard');
82+
83+
const startRename = () => {
84+
setIsRenaming(true);
85+
setEditName(dashboardName);
86+
};
87+
88+
const cancelRename = () => {
89+
setIsRenaming(false);
90+
setEditName(dashboardName);
91+
};
92+
8293
const submitRename = () => {
83-
if (!rename || selectedDashboard?.name === rename) {
84-
setRename(null);
94+
const newName = editName.trim();
95+
if (dashboardName === newName) {
96+
setIsRenaming(false);
8597
return;
8698
}
87-
renameDashboardMutate();
99+
setIsRenaming(false);
100+
renameDashboardMutate({ name: newName });
88101
};
89102

103+
const handleKeyDown = (e: React.KeyboardEvent) => {
104+
if (e.key === 'Enter') {
105+
submitRename();
106+
} else if (e.key === 'Escape') {
107+
cancelRename();
108+
}
109+
};
110+
111+
useEffect(() => {
112+
if (isRenaming && renameRef.current) {
113+
renameRef.current.focus();
114+
renameRef.current.select();
115+
}
116+
}, [isRenaming]);
117+
90118
return (
91-
<div className="flex h-16 shrink-0 items-center justify-between border-b px-4">
119+
<div className="flex h-12 shrink-0 items-center justify-between border-b px-4">
92120
<Head>
93-
<title>
94-
{selectedDashboard?.name ? `${selectedDashboard?.name} - ${brandName}` : brandName}
95-
</title>
121+
<title>{dashboardName ? `${dashboardName} - ${brandName}` : brandName}</title>
96122
</Head>
97-
<DashboardSwitcher
98-
className={cn('w-44', {
99-
hidden: rename !== null,
100-
})}
101-
dashboardId={dashboardId}
102-
onChange={(dashboardId) => {
103-
router.push({
104-
pathname: '/base/[baseId]/dashboard/[dashboardId]',
105-
query: { baseId, dashboardId },
106-
});
107-
}}
108-
/>
109-
<Input
110-
ref={renameRef}
111-
className={cn('w-44', {
112-
hidden: rename === null,
113-
})}
114-
value={rename ?? ''}
115-
onBlur={() => {
116-
submitRename();
117-
}}
118-
onKeyDown={(e) => {
119-
if (e.key === 'Enter') {
120-
submitRename();
121-
}
122-
if (e.key === 'Escape') {
123-
setRename(null);
124-
}
125-
}}
126-
onChange={(e) => setRename(e.target.value)}
127-
/>
123+
{isRenaming ? (
124+
<Input
125+
ref={renameRef}
126+
className="max-w-60"
127+
value={editName ?? ''}
128+
onBlur={submitRename}
129+
onKeyDown={handleKeyDown}
130+
onChange={(e) => setEditName(e.target.value)}
131+
/>
132+
) : (
133+
<Button
134+
variant="ghost"
135+
size="sm"
136+
className="justify-start text-sm"
137+
disabled={!canManage}
138+
onClick={startRename}
139+
>
140+
<span className="truncate"> {dashboardName}</span>
141+
</Button>
142+
)}
143+
128144
<div className="flex items-center gap-2">
129145
{canManage && (
130146
<AddPluginDialog dashboardId={dashboardId}>
@@ -142,12 +158,7 @@ export const DashboardHeader = (props: { dashboardId: string }) => {
142158
</Button>
143159
</DropdownMenuTrigger>
144160
<DropdownMenuContent align="end" className="relative min-w-36 overflow-hidden">
145-
<DropdownMenuItem
146-
onSelect={() => {
147-
setRename(selectedDashboard?.name ?? null);
148-
setTimeout(() => renameRef.current?.focus(), 200);
149-
}}
150-
>
161+
<DropdownMenuItem onSelect={startRename}>
151162
<Edit className="mr-1.5" />
152163
{t('common:actions.rename')}
153164
</DropdownMenuItem>

0 commit comments

Comments
 (0)