MCPcopy Index your code
hub / github.com/coder/coder / useAppLink

Function useAppLink

site/src/modules/apps/useAppLink.ts:30–116  ·  view source on GitHub ↗
(
	app: WorkspaceApp,
	{ agent, workspace }: UseAppLinkParams,
)

Source from the content-addressed store, hash-verified

28};
29
30export const useAppLink = (
31 app: WorkspaceApp,
32 { agent, workspace }: UseAppLinkParams,
33): AppLink => {
34 const label = app.display_name ?? app.slug;
35 const { proxy } = useProxy();
36 const { data: apiKeyResponse } = useQuery({
37 ...apiKey(),
38 enabled: isExternalApp(app) && needsSessionToken(app),
39 });
40
41 const href = getAppHref(app, {
42 agent,
43 workspace,
44 token: apiKeyResponse?.key,
45 path: proxy.preferredPathAppURL,
46 host: proxy.preferredWildcardHostname,
47 });
48
49 const onClick = (e: React.MouseEvent) => {
50 if (!e.currentTarget.getAttribute("href")) {
51 return;
52 }
53
54 // External apps with custom protocols (non-HTTP) need special handling
55 // for error detection when the app isn't installed.
56 const isExternalProtocolApp =
57 app.external && app.url && !app.url.startsWith("http");
58
59 if (isExternalProtocolApp) {
60 // When browser recognizes the protocol and is able to navigate to the app,
61 // it will blur away, and will stop the timer. Otherwise,
62 // an error message will be displayed.
63 const openAppExternallyFailedTimeout = 1500;
64 const openAppExternallyFailed = setTimeout(() => {
65 // Check if this is a JetBrains IDE app
66 // starts with "jetbrains-gateway://connect#type=coder" (from https://registry.coder.com/modules/coder/jetbrains-gateway)
67 const isJetBrainsGateway = app.url?.startsWith("jetbrains-gateway:");
68 // starts with "jetbrains://gateway/coder" (from https://registry.coder.com/modules/coder/jetbrains)
69 const isJetBrainsToolbox = app.url?.startsWith("jetbrains:");
70
71 // Check if this is a coder:// URL
72 const isCoderApp = app.url?.startsWith("coder:");
73
74 if (isJetBrainsGateway) {
75 toast.error(`Failed to open "${label}".`, {
76 description: "JetBrains Gateway must be installed.",
77 });
78 } else if (isJetBrainsToolbox) {
79 toast.error(`Failed to open "${label}".`, {
80 description: "JetBrains Toolbox must be installed.",
81 });
82 } else if (isCoderApp) {
83 toast.error(`Failed to open "${label}".`, {
84 description: "Coder Desktop must be installed.",
85 });
86 } else {
87 toast.error(`Failed to open "${label}".`, {

Callers 7

AppLinkFunction · 0.90
AppLinkFunction · 0.90
TaskAppIFrameFunction · 0.90
ExternalAppMenuItemFunction · 0.90
TaskAppTabFunction · 0.90
IconAppLinkFunction · 0.90
AppMenuItemFunction · 0.90

Calls 5

useProxyFunction · 0.90
apiKeyFunction · 0.90
isExternalAppFunction · 0.90
needsSessionTokenFunction · 0.90
getAppHrefFunction · 0.90

Tested by

no test coverage detected