Skip to content

Commit 577636c

Browse files
committed
[TOOL-3156] Dashboard: Fix localhost engine not loading, fetch engine permission on client side (#6013)
<!-- start pr-codex --> ## PR-Codex overview This PR enhances the engine access permission handling in the dashboard. It introduces a new component, `EnsureEnginePermission`, which checks permissions before rendering engine details and handles various error states more effectively. ### Detailed summary - Added `account` to the return object in `getEngineInstancePageMeta.ts`. - Improved URL handling in `getEngineAccessPermission.ts`. - Introduced `EnsureEnginePermission` component. - Replaced direct permission checks in `Layout` with `EnsureEnginePermission`. - Removed `EngineInstanceLayoutContent` component. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 1d844ac commit 577636c

File tree

4 files changed

+113
-67
lines changed

4 files changed

+113
-67
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"use client";
2+
3+
import type { EngineInstance } from "@3rdweb-sdk/react/hooks/useEngine";
4+
import { useQuery } from "@tanstack/react-query";
5+
import type React from "react";
6+
import GenericLoadingPage from "../../../../ecosystem/loading";
7+
import { getEngineAccessPermission } from "../../../_utils/getEngineAccessPermission";
8+
import { EngineErrorPage } from "./EngineErrorPage";
9+
10+
export function EnsureEnginePermission(props: {
11+
engineId: string;
12+
accountId: string;
13+
authToken: string;
14+
children: React.ReactNode;
15+
teamSlug: string;
16+
instance: EngineInstance;
17+
}) {
18+
const { instance } = props;
19+
const rootPath = `/team/${props.teamSlug}/~/engine`;
20+
21+
const permissionQuery = useQuery({
22+
queryKey: [
23+
"engine-permission",
24+
{
25+
instanceUrl: instance.url,
26+
authToken: props.authToken,
27+
},
28+
],
29+
queryFn: () => {
30+
const url = instance.url;
31+
if (!url) {
32+
throw new Error();
33+
}
34+
35+
return getEngineAccessPermission({
36+
authToken: props.authToken,
37+
instanceUrl: url,
38+
});
39+
},
40+
retry: false,
41+
});
42+
43+
if (permissionQuery.isPending) {
44+
return <GenericLoadingPage />;
45+
}
46+
47+
if (!permissionQuery.data) {
48+
return (
49+
<EngineErrorPage rootPath={rootPath}>
50+
Failed to verify access to engine instance
51+
</EngineErrorPage>
52+
);
53+
}
54+
55+
const permission = permissionQuery.data;
56+
57+
if (!permission.ok) {
58+
if (permission.status === 404) {
59+
return (
60+
<EngineErrorPage rootPath={rootPath}>
61+
<p> Engine instance not found </p>
62+
</EngineErrorPage>
63+
);
64+
}
65+
66+
if (permission.fetchFailed) {
67+
return (
68+
<EngineErrorPage rootPath={rootPath}>
69+
<p> Engine instance could not be reached </p>
70+
</EngineErrorPage>
71+
);
72+
}
73+
74+
if (permission.status === 401 || permission.status === 500) {
75+
return (
76+
<EngineErrorPage rootPath={rootPath}>
77+
<div>
78+
<p>You are not an admin for this Engine instance. </p>
79+
<p> Contact the owner to add your wallet as an admin</p>
80+
</div>
81+
</EngineErrorPage>
82+
);
83+
}
84+
}
85+
86+
return <div>{props.children}</div>;
87+
}

apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/layout.tsx

Lines changed: 15 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import Link from "next/link";
77
import { getValidAccount } from "../../../../../../../account/settings/getAccount";
88
import { getAuthToken } from "../../../../../../../api/lib/getAuthToken";
99
import { loginRedirect } from "../../../../../../../login/loginRedirect";
10-
import { getEngineAccessPermission } from "../../_utils/getEngineAccessPermission";
1110
import { getEngineInstance } from "../../_utils/getEngineInstance";
1211
import { EngineErrorPage } from "./_components/EngineErrorPage";
1312
import { EngineSidebarLayout } from "./_components/EnginePageLayout";
13+
import { EnsureEnginePermission } from "./_components/EnsureEnginePermission";
1414
import { EngineVersionBadge } from "./_components/version";
1515

1616
export default async function Layout(props: {
@@ -49,78 +49,28 @@ export default async function Layout(props: {
4949
);
5050
}
5151

52-
const permission = await getEngineAccessPermission({
53-
authToken,
54-
instanceUrl: instance.url,
55-
});
56-
5752
return (
5853
<EngineSidebarLayout engineId={params.engineId} teamSlug={params.team_slug}>
59-
<EngineInstanceLayoutContent
54+
<EnsureEnginePermission
55+
teamSlug={params.team_slug}
56+
accountId={account.id}
57+
authToken={authToken}
58+
engineId={params.engineId}
6059
instance={instance}
61-
permission={permission}
62-
rootPath={engineRootLayoutPath}
63-
team_slug={params.team_slug}
6460
>
65-
{props.children}
66-
</EngineInstanceLayoutContent>
61+
<div>
62+
<EngineInstanceHeader
63+
instance={instance}
64+
rootPath={engineRootLayoutPath}
65+
teamSlug={params.team_slug}
66+
/>
67+
{props.children}
68+
</div>
69+
</EnsureEnginePermission>
6770
</EngineSidebarLayout>
6871
);
6972
}
7073

71-
function EngineInstanceLayoutContent(props: {
72-
permission: {
73-
ok: boolean;
74-
status: number;
75-
};
76-
instance: EngineInstance;
77-
rootPath: string;
78-
children: React.ReactNode;
79-
team_slug: string;
80-
}) {
81-
const { instance, permission, rootPath, team_slug } = props;
82-
83-
if (!permission.ok) {
84-
if (permission.status === 404) {
85-
return (
86-
<EngineErrorPage rootPath={rootPath}>
87-
<p> Engine Instance Not Found </p>
88-
</EngineErrorPage>
89-
);
90-
}
91-
92-
if (permission.status === 500) {
93-
return (
94-
<EngineErrorPage rootPath={rootPath}>
95-
<p> Engine Instance Could Not Be Reached </p>
96-
</EngineErrorPage>
97-
);
98-
}
99-
100-
if (permission.status === 401) {
101-
return (
102-
<EngineErrorPage rootPath={rootPath}>
103-
<div>
104-
<p>You are not an admin for this Engine instance. </p>
105-
<p> Contact the owner to add your wallet as an admin</p>
106-
</div>
107-
</EngineErrorPage>
108-
);
109-
}
110-
}
111-
112-
return (
113-
<div>
114-
<EngineInstanceHeader
115-
instance={instance}
116-
rootPath={rootPath}
117-
teamSlug={team_slug}
118-
/>
119-
{props.children}
120-
</div>
121-
);
122-
}
123-
12474
function EngineInstanceHeader(props: {
12575
instance: EngineInstance;
12676
rootPath: string;

apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/_utils/getEngineAccessPermission.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1+
"use client";
2+
3+
// can not fetch engine permission on server - instance url can be localhost url
4+
15
export async function getEngineAccessPermission(params: {
26
authToken: string;
37
instanceUrl: string;
48
}) {
59
try {
6-
const res = await fetch(`${params.instanceUrl}auth/permissions/get-all`, {
10+
const instanceUrl = params.instanceUrl.endsWith("/")
11+
? params.instanceUrl
12+
: `${params.instanceUrl}/`;
13+
14+
const res = await fetch(`${instanceUrl}auth/permissions/get-all`, {
715
method: "GET",
816
headers: {
917
"Content-Type": "application/json",
@@ -19,6 +27,7 @@ export async function getEngineAccessPermission(params: {
1927
return {
2028
ok: false,
2129
status: 500,
30+
fetchFailed: true,
2231
};
2332
}
2433
}

apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/_utils/getEngineInstancePageMeta.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ export async function engineInstancePageHandler(params: {
3030
notFound();
3131
}
3232

33-
return { instance, authToken };
33+
return { instance, authToken, account };
3434
}

0 commit comments

Comments
 (0)