Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/compute/launcher.tsx
5874 views
1
/*
2
Launcher buttons shown for a running compute server.
3
*/
4
5
import { Button, Modal, Spin, Tooltip } from "antd";
6
import { useMemo, useState } from "react";
7
8
import { useTypedRedux } from "@cocalc/frontend/app-framework";
9
import { Icon } from "@cocalc/frontend/components";
10
import ShowError from "@cocalc/frontend/components/error";
11
import { useImages } from "@cocalc/frontend/compute/images-hook";
12
13
import { useServer } from "./compute-server";
14
import { getApps } from "./menu";
15
import { LauncherButton, getRoute } from "./proxy";
16
17
export default function Launcher({
18
style,
19
configuration,
20
data,
21
compute_server_id,
22
project_id,
23
}) {
24
const [appName, setAppName] = useState<string>("");
25
const image = configuration?.image;
26
if (image == null || data == null || configuration == null) {
27
return null;
28
}
29
const apps = getApps(image);
30
if (!apps) {
31
return null;
32
}
33
return (
34
<div style={style}>
35
{!!appName && (
36
<AppLauncherModal
37
id={compute_server_id}
38
name={appName}
39
project_id={project_id}
40
close={() => setAppName("")}
41
/>
42
)}
43
{/*<Button
44
onClick={() => setAppName("explorer")}
45
type="text"
46
size="small"
47
style={{ color: "#666" }}
48
>
49
<Icon name="folder-open" /> Explorer
50
</Button>*/}
51
52
{apps["jupyterlab"] != null && (
53
<Tooltip title={apps["jupyterlab"].tip} placement="left">
54
<Button
55
onClick={() => setAppName("jupyterlab")}
56
type="text"
57
size="small"
58
style={{ color: "#666" }}
59
>
60
<Icon
61
name={apps["jupyterlab"].icon}
62
style={{ marginRight: "-5px" }}
63
/>
64
JupyterLab
65
</Button>
66
</Tooltip>
67
)}
68
{apps["vscode"] != null && (
69
<Tooltip title={apps["vscode"].tip} placement="left">
70
<Button
71
onClick={() => setAppName("vscode")}
72
type="text"
73
size="small"
74
style={{ color: "#666" }}
75
>
76
<Icon name={apps["vscode"].icon} style={{ marginRight: "-5px" }} />
77
VS Code
78
</Button>
79
</Tooltip>
80
)}
81
{apps["xpra"] != null && (
82
<Tooltip title={apps["xpra"].tip} placement="left">
83
<Button
84
onClick={() => setAppName("xpra")}
85
type="text"
86
size="small"
87
style={{ color: "#666" }}
88
>
89
<Icon name={apps["xpra"].icon} style={{ marginRight: "-5px" }} />
90
Desktop
91
</Button>
92
</Tooltip>
93
)}
94
</div>
95
);
96
}
97
98
function AppLauncher({
99
name,
100
configuration,
101
data,
102
compute_server_id,
103
project_id,
104
IMAGES,
105
}) {
106
const [error, setError] = useState<string>("");
107
const compute_servers_dns = useTypedRedux("customize", "compute_servers_dns");
108
const image = configuration.image;
109
const app = (IMAGES[image]?.apps ?? IMAGES["defaults"]?.apps ?? [])[name];
110
const route = useMemo(() => {
111
if (app == null) {
112
return null;
113
}
114
try {
115
return getRoute({ app, configuration, IMAGES });
116
} catch (err) {
117
setError(`${err}`);
118
return null;
119
}
120
}, [app, configuration, IMAGES]);
121
122
if (app == null) {
123
return <ShowError error={`Unknown application '${name}'`} />;
124
}
125
126
return (
127
<div>
128
{route && (
129
<LauncherButton
130
name={name}
131
app={app}
132
compute_server_id={compute_server_id}
133
project_id={project_id}
134
configuration={configuration}
135
data={data}
136
compute_servers_dns={compute_servers_dns}
137
setError={setError}
138
route={route}
139
noHide
140
autoLaunch
141
/>
142
)}
143
<ShowError
144
error={error}
145
setError={setError}
146
style={{ margin: "15px 0", width: "100%" }}
147
/>
148
</div>
149
);
150
}
151
152
// function ExplorerLauncher({ compute_server_id, project_id }) {
153
// return (
154
// <div>
155
// {compute_server_id} {project_id}
156
// </div>
157
// );
158
// }
159
160
export function AppLauncherModal({
161
name,
162
id,
163
project_id,
164
close,
165
}: {
166
name: string;
167
id: number;
168
project_id: string;
169
close: () => void;
170
}) {
171
const server = useServer({ id, project_id });
172
const [IMAGES] = useImages();
173
if (server == null || IMAGES == null) {
174
return <Spin />;
175
}
176
const image = server.configuration?.image ?? "defaults";
177
const apps = getApps(image);
178
179
return (
180
<Modal
181
title={
182
<>
183
<Icon
184
name={apps[name]?.icon ?? "global"}
185
style={{ marginRight: "5px" }}
186
/>
187
{apps[name]?.label ?? name}
188
</>
189
}
190
open
191
onOk={close}
192
onCancel={close}
193
destroyOnHidden
194
>
195
{apps[name]?.tip}
196
<AppLauncher
197
name={name}
198
configuration={server.configuration}
199
data={server.data}
200
compute_server_id={server.id}
201
project_id={project_id}
202
IMAGES={IMAGES}
203
/>
204
</Modal>
205
);
206
}
207
208