Skip to content

Commit 3ba8403

Browse files
committed
add animation when remove and add resource
1 parent 0345677 commit 3ba8403

14 files changed

+302
-318
lines changed

package-lock.json

+69
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
"lodash": "^4.17.21",
9696
"lucia": "^3.2.0",
9797
"lucide-react": "^0.474.0",
98+
"motion": "^12.4.3",
9899
"next": "15.1.4",
99100
"next-themes": "^0.4.4",
100101
"oslo": "^1.1.3",

src/app/(outerbase)/layout.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { OuterbaseSessionProvider } from "@/app/(outerbase)/session-provider";
22
import ClientOnly from "@/components/client-only";
33
import ThemeLayout from "../(theme)/theme_layout";
4-
import AuthProvider from "./auth-provider";
54
import { WorkspaceProvider } from "./workspace-provider";
65

76
export default function OuterbaseLayout({
@@ -13,9 +12,7 @@ export default function OuterbaseLayout({
1312
<ThemeLayout>
1413
<ClientOnly>
1514
<OuterbaseSessionProvider>
16-
<AuthProvider>
17-
<WorkspaceProvider>{children}</WorkspaceProvider>
18-
</AuthProvider>
15+
<WorkspaceProvider>{children}</WorkspaceProvider>
1916
</OuterbaseSessionProvider>
2017
</ClientOnly>
2118
</ThemeLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import CopyableText from "@/components/copyable-text";
2+
import { createDialog } from "@/components/create-dialog";
3+
import LabelInput from "@/components/label-input";
4+
import { Button } from "@/components/orbit/button";
5+
import {
6+
DialogDescription,
7+
DialogFooter,
8+
DialogHeader,
9+
DialogTitle,
10+
} from "@/components/ui/dialog";
11+
import { LucideLoader } from "lucide-react";
12+
import { useCallback, useState } from "react";
13+
import { deleteLocalDashboard } from "./hooks";
14+
15+
export const deleteLocalBoardDialog = createDialog<{
16+
boardId: string;
17+
boardName: string;
18+
}>(({ close, boardName, boardId }) => {
19+
const [loading, setLoading] = useState(false);
20+
const [name, setName] = useState("");
21+
22+
const deleteClicked = useCallback(() => {
23+
if (name !== boardName) return;
24+
25+
setLoading(true);
26+
27+
deleteLocalDashboard(boardId)
28+
.then(() => {
29+
close(undefined);
30+
})
31+
.finally(() => {
32+
setLoading(false);
33+
});
34+
}, [name, boardId, close, boardName]);
35+
36+
return (
37+
<>
38+
<DialogHeader>
39+
<DialogTitle>Confirm deletion of board {boardName}</DialogTitle>
40+
<DialogDescription>
41+
All saved charts and any other contributions made to your Dashboard
42+
will be deleted. This action is permanent and <strong>cannot</strong>{" "}
43+
be undone.
44+
</DialogDescription>
45+
</DialogHeader>
46+
47+
<div className="flex flex-col gap-4">
48+
<div>
49+
<CopyableText text={boardName} />
50+
</div>
51+
52+
<LabelInput
53+
label="Enter the name of this Base to confirm:"
54+
placeholder="Board name"
55+
value={name}
56+
required
57+
onChange={(e) => setName(e.currentTarget.value)}
58+
/>
59+
</div>
60+
61+
<DialogFooter>
62+
<Button
63+
variant={"destructive"}
64+
disabled={loading || boardName !== name}
65+
onClick={deleteClicked}
66+
>
67+
{loading && <LucideLoader className="mr-2 h-4 w-4 animate-spin" />}I
68+
understand, delete this board
69+
</Button>
70+
<Button variant={"secondary"} onClick={() => close(undefined)}>
71+
Cancel
72+
</Button>
73+
</DialogFooter>
74+
</>
75+
);
76+
});

src/app/(outerbase)/local/hooks.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { LocalDashboardData, localDb } from "@/indexdb";
2-
import useSWR from "swr";
2+
import useSWR, { mutate } from "swr";
33

44
export function useLocalDashboardList() {
55
return useSWR(
@@ -34,3 +34,8 @@ export async function createLocalDashboard(boardName: string) {
3434
await localDb.table("board").add({ id, content: data });
3535
return data;
3636
}
37+
38+
export async function deleteLocalDashboard(boardId: string) {
39+
await localDb.table("board").delete(boardId);
40+
mutate("/dashboards/local");
41+
}

src/app/(outerbase)/local/page.tsx

+17-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import NavigationLayout from "../nav-layout";
1212
import NewResourceButton from "../new-resource-button";
1313
import { ResourceItemList, ResourceItemProps } from "../resource-item-helper";
1414
import { createLocalBoardDialog } from "./dialog-board-create";
15+
import { deleteLocalBoardDialog } from "./dialog-board-delete";
1516
import { useLocalDashboardList } from "./hooks";
1617

1718
export default function LocalConnectionPage() {
@@ -49,18 +50,25 @@ export default function LocalConnectionPage() {
4950
);
5051
}, [dashboardList]);
5152

52-
const onCreateBoardClicked = useCallback(() => {
53+
const onBoardCreate = useCallback(() => {
5354
createLocalBoardDialog.show({}).then(() => {
54-
refreshDashboard(undefined, { revalidate: true });
55+
refreshDashboard();
5556
});
5657
}, [refreshDashboard]);
5758

59+
const onBoardRemove = useCallback((deletedResource: ResourceItemProps) => {
60+
deleteLocalBoardDialog
61+
.show({ boardId: deletedResource.id, boardName: deletedResource.name })
62+
.then()
63+
.catch();
64+
}, []);
65+
5866
return (
5967
<NavigationLayout>
60-
<NavigationHeader title={"Local Worksapce"} />
68+
<NavigationHeader />
6169
<div className="flex flex-1 flex-col content-start gap-4 overflow-x-hidden overflow-y-auto p-4">
6270
<div className="flex gap-2">
63-
<NewResourceButton onCreateBoard={onCreateBoardClicked} />
71+
<NewResourceButton onCreateBoard={onBoardCreate} />
6472
</div>
6573

6674
<div className="my-4 flex gap-4">
@@ -86,7 +94,11 @@ export default function LocalConnectionPage() {
8694
</button>
8795
</div>
8896

89-
<ResourceItemList boards={dashboardResources} bases={baseResources} />
97+
<ResourceItemList
98+
boards={dashboardResources}
99+
bases={baseResources}
100+
onBoardRemove={onBoardRemove}
101+
/>
90102
</div>
91103
</NavigationLayout>
92104
);

src/app/(outerbase)/nav-header-local.tsx

Whitespace-only changes.

src/app/(outerbase)/nav-header.tsx

+38-16
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,57 @@
11
import { cn } from "@/lib/utils";
22
import { Cardholder, Database, Gear } from "@phosphor-icons/react";
3+
import Link from "next/link";
4+
import { useParams, usePathname } from "next/navigation";
5+
import { useWorkspaces } from "./workspace-provider";
36

4-
interface NavigationHeaderProps {
5-
title: string;
6-
}
7-
8-
export default function NavigationHeader({ title }: NavigationHeaderProps) {
7+
export default function NavigationHeader() {
98
const tabClassName =
109
"p-2 border-b-2 border-background flex gap-2 items-center h-full";
1110
const selectedTabClassName = cn(tabClassName, "border-orange-500");
1211

12+
const { workspaceId } = useParams<{ workspaceId: string }>();
13+
const { currentWorkspace } = useWorkspaces();
14+
const pathname = usePathname();
15+
1316
return (
1417
<div className="bg-background flex h-12 flex-col gap-1 border-b px-6">
15-
<ul className="flex h-full gap-2 text-base">
16-
<li className={selectedTabClassName}>
18+
<nav className="flex h-full gap-2 text-base">
19+
<Link
20+
className={
21+
pathname.endsWith(workspaceId) ? selectedTabClassName : tabClassName
22+
}
23+
href={`/w/${workspaceId}`}
24+
>
1725
<Database />
1826
Resources
19-
</li>
20-
<li className={tabClassName}>
27+
</Link>
28+
<Link
29+
className={
30+
pathname.endsWith(`/${workspaceId}/settings`)
31+
? selectedTabClassName
32+
: tabClassName
33+
}
34+
href={`/w/${workspaceId}/settings`}
35+
>
2136
<Gear />
2237
Settings
23-
</li>
24-
<li className={tabClassName}>
38+
</Link>
39+
<Link
40+
className={
41+
pathname.endsWith(`/${workspaceId}/billing`)
42+
? selectedTabClassName
43+
: tabClassName
44+
}
45+
href={`/w/${workspaceId}/billing`}
46+
>
2547
<Cardholder />
2648
Billing
27-
</li>
49+
</Link>
2850

29-
<li className="flex flex-1 items-center justify-end font-bold">
30-
{title}
31-
</li>
32-
</ul>
51+
<div className="flex flex-1 items-center justify-end font-bold">
52+
{currentWorkspace?.name ?? ""}
53+
</div>
54+
</nav>
3355
</div>
3456
);
3557
}

0 commit comments

Comments
 (0)