Skip to content

Commit 8e2cffe

Browse files
committed
Refactor ConfigConnection to use URL instead of port; update related components and services. This includes changes to context, provider, screens, and connection checks to accommodate the new URL structure. Additionally, several unused tools and services have been removed to streamline the codebase.
1 parent 8e1a146 commit 8e2cffe

File tree

70 files changed

+4436
-1949
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+4436
-1949
lines changed

‎src/components/ConfigConnection/ConfigConnectionContext.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { createContext } from "react";
22

33
export const ConfigConnectionContext = createContext<{
44
data: {
5-
port: number;
5+
url: string;
66
siteId: string;
77
};
8-
setData: (data: { port: number; siteId: string }) => void;
8+
setData: (data: { url: string; siteId: string }) => void;
99
}>({
1010
data: {
11-
port: 3000,
11+
url: "http://localhost:1338",
1212
siteId: "",
1313
},
1414
setData: () => {},

‎src/components/ConfigConnection/ConfigConnectionProvider.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ export const ConfigConnectionProvider = ({
77
children: React.ReactNode;
88
}) => {
99
const [data, setData] = useState<{
10-
port: number;
10+
url: string;
1111
siteId: string;
1212
}>({
13-
port: 3000,
13+
url: "://localhost:1338",
1414
siteId: "",
1515
});
1616
return (

‎src/components/Screens/Home.tsx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { Badge } from "../ui/badge";
1818

1919
export const HomeScreen = () => {
2020
const {
21-
data: { port, siteId },
21+
data: { url, siteId },
2222
} = useConfigConnection();
2323

2424
const { setCurrentScreen } = useScreenManager();
@@ -27,8 +27,8 @@ export const HomeScreen = () => {
2727
string[]
2828
>([]);
2929
useEffect(() => {
30-
if (port) {
31-
initRPC(port, siteId, {
30+
if (url) {
31+
initRPC(url, siteId, {
3232
log: (message) => {
3333
setToolCallLogs((prev) => [
3434
`${message}`,
@@ -48,7 +48,7 @@ export const HomeScreen = () => {
4848
} else {
4949
setCurrentScreen("SPLASH");
5050
}
51-
}, [port, setCurrentScreen, siteId]);
51+
}, [url, setCurrentScreen, siteId]);
5252

5353
if (!isConnected) {
5454
return (

‎src/components/Screens/Splash.tsx‎

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,44 +17,48 @@ import { LoaderCircle } from "lucide-react";
1717
export const SplashScreen = () => {
1818
const { setCurrentScreen } = useScreenManager();
1919
const { setData } = useConfigConnection();
20-
const [port, setPort] = useState(3000);
20+
const [url, setUrl] = useState("http://localhost:1338");
2121
const [isLoading, setIsLoading] = useState(false);
2222

2323
const handleConnect = async () => {
2424
try {
2525
setIsLoading(true);
2626
toast.info("Checking Connection...");
27-
const isConnected = await checkConnection(port);
27+
const isConnected = await checkConnection(url);
2828
if (isConnected) {
2929
const site = await webflow.getSiteInfo();
30-
setData({ port, siteId: site.siteId });
30+
setData({ url, siteId: site.siteId });
3131
setCurrentScreen("HOME");
3232
toast.success("Connection Validated");
3333
} else {
34-
toast.error("Failed to connect to MCP Server");
34+
toast.error("Failed to connect to MCP Server", {
35+
description:
36+
"Please check the URL and try again. ask LLM to get the correct URL if needed.",
37+
});
3538
}
3639
} catch (error) {
3740
console.error(error);
38-
toast.error("Failed to connect to MCP Server");
41+
toast.error("Failed to connect to MCP Server", {
42+
description:
43+
"Please check the URL and try again. ask LLM to get the correct URL if needed.",
44+
});
3945
} finally {
4046
setIsLoading(false);
4147
}
4248
};
4349

4450
return (
45-
<div className="flex flex-col justify-center items-center h-screen gap-3">
51+
<div className="flex flex-col justify-center items-center h-screen gap-3 p-3">
4652
<Card>
4753
<CardHeader>
4854
<CardTitle>Enter Port</CardTitle>
4955
</CardHeader>
5056
<CardContent className="flex flex-col gap-2">
5157
<Input
52-
type="number"
53-
placeholder="Enter Port"
54-
value={port}
55-
onChange={(e) =>
56-
setPort(Number(e.target.value))
57-
}
58+
type="url"
59+
placeholder="Enter URL"
60+
value={url}
61+
onChange={(e) => setUrl(e.target.value)}
5862
/>
5963
<Button
6064
onClick={handleConnect}
@@ -66,6 +70,13 @@ export const SplashScreen = () => {
6670
"Connect"
6771
)}
6872
</Button>
73+
<div className="flex flex-col gap-1 mt-2">
74+
<p className="text-sm text-text3">Need Help?</p>
75+
<p className="text-xs text-text3">
76+
Ask LLM to get "Get Webflow MCP App Connection
77+
Info". put the localhost url in above input.
78+
</p>
79+
</div>
6980
</CardContent>
7081
</Card>
7182
</div>

‎src/services/checkConnection.ts‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { debug } from "./debug";
22

3-
export const checkConnection = async (port: number) => {
3+
export const checkConnection = async (url: string) => {
44
try {
5-
const response = await fetch(
6-
`http://localhost:${port}`
7-
);
5+
const response = await fetch(url);
86
return response.ok;
97
} catch (error) {
108
debug(error);
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import getAssetFolderInfo, {
2+
AssetFolderDetailedInfo,
3+
} from "@/utils/getAssetFolderInfo";
4+
import { getError } from "./helper/errorHelper";
5+
import getAssetInfo, {
6+
AssetDetailedInfo,
7+
} from "@/utils/getAssetInfo";
8+
9+
type Action = {
10+
create_folder?: {
11+
/** The name of the folder to create */
12+
name: string;
13+
14+
/** The id of the parent folder to create the folder in */
15+
parent_folder_id?: string;
16+
};
17+
18+
get_all_assets_and_folders?: {
19+
/** Query to get all assets and folders on the site */
20+
query: "all" | "folders" | "assets";
21+
22+
/** Filter assets by ids */
23+
filter_assets_by_ids?: string[];
24+
};
25+
26+
update_asset?: {
27+
/** The id of the asset to update */
28+
asset_id: string;
29+
30+
/** The name of the asset to update */
31+
name?: string;
32+
33+
/** The alt text of the asset to update */
34+
alt_text?: string;
35+
36+
/**
37+
* The id of the parent folder to move the asset to.
38+
*/
39+
parent_folder_id?: string;
40+
};
41+
};
42+
43+
type ActionsArray = Action[];
44+
const asset_tool = async (actions: ActionsArray) => {
45+
const result: {
46+
status: "success" | "error";
47+
message: string;
48+
data: any;
49+
}[] = [];
50+
let AssetFolders: AssetFolder[] = [];
51+
for (const action of actions) {
52+
try {
53+
if (action.create_folder) {
54+
if (!action.create_folder.name) {
55+
throw new Error("Folder name is required");
56+
}
57+
const folder = await webflow.createAssetFolder(
58+
action.create_folder.name,
59+
action.create_folder.parent_folder_id
60+
);
61+
result.push({
62+
status: "success",
63+
message: "Folder created successfully",
64+
data: await getAssetFolderInfo(folder),
65+
});
66+
}
67+
if (action.get_all_assets_and_folders) {
68+
const query =
69+
action.get_all_assets_and_folders.query;
70+
const filterAssetId =
71+
action.get_all_assets_and_folders
72+
.filter_assets_by_ids || [];
73+
const assets: AssetDetailedInfo[] = [];
74+
const folders: AssetFolderDetailedInfo[] = [];
75+
if (query === "all" || query === "assets") {
76+
const _assets = (
77+
await webflow.getAllAssets()
78+
).filter((asset) => {
79+
if (filterAssetId.length > 0) {
80+
return filterAssetId.includes(asset.id);
81+
}
82+
return true;
83+
});
84+
const _assetsInfo = await Promise.all(
85+
_assets.map(getAssetInfo)
86+
);
87+
assets.push(..._assetsInfo);
88+
}
89+
if (query === "all" || query === "folders") {
90+
const _folders =
91+
await webflow.getAllAssetFolders();
92+
AssetFolders = _folders;
93+
const _foldersInfo = await Promise.all(
94+
_folders.map(getAssetFolderInfo)
95+
);
96+
folders.push(..._foldersInfo);
97+
}
98+
result.push({
99+
status: "success",
100+
message:
101+
"Assets and folders fetched successfully",
102+
data: {
103+
assets,
104+
folders,
105+
},
106+
});
107+
}
108+
109+
if (action.update_asset) {
110+
const asset = await webflow.getAssetById(
111+
action.update_asset.asset_id
112+
);
113+
if (!asset) {
114+
result.push({
115+
status: "error",
116+
message: "Asset not found",
117+
data: null,
118+
});
119+
continue;
120+
}
121+
if (action.update_asset.name) {
122+
await asset.setName(action.update_asset.name);
123+
}
124+
if (action.update_asset.alt_text) {
125+
await asset.setAltText(
126+
action.update_asset.alt_text
127+
);
128+
}
129+
if (action.update_asset.parent_folder_id) {
130+
const folders = AssetFolders.length
131+
? AssetFolders
132+
: await webflow.getAllAssetFolders();
133+
const folder = folders.find(
134+
(folder) =>
135+
folder.id ===
136+
action.update_asset!.parent_folder_id!
137+
);
138+
if (!folder) {
139+
result.push({
140+
status: "error",
141+
message: `Folder with id ${action.update_asset!
142+
.parent_folder_id!} not found for asset ${
143+
action.update_asset!.asset_id
144+
}`,
145+
data: null,
146+
});
147+
} else {
148+
await asset.setParent(folder);
149+
}
150+
}
151+
result.push({
152+
status: "success",
153+
message: "Asset updated successfully",
154+
data: await getAssetInfo(asset),
155+
});
156+
}
157+
} catch (error) {
158+
console.log(error);
159+
result.push({
160+
status: "error",
161+
message: getError(error),
162+
data: null,
163+
});
164+
}
165+
}
166+
return result;
167+
};
168+
169+
export default asset_tool;

0 commit comments

Comments
 (0)