Skip to content

Commit 91fe550

Browse files
committed
[dashboard] simplify autostart
1 parent e16b836 commit 91fe550

File tree

4 files changed

+82
-113
lines changed

4 files changed

+82
-113
lines changed

components/dashboard/src/components/SelectIDEComponent.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { FC, useCallback, useEffect, useMemo } from "react";
99
import { DropDown2, DropDown2Element, DropDown2SelectedElement } from "./DropDown2";
1010
import Editor from "../icons/Editor.svg";
1111
import { useIDEOptions } from "../data/ide-options/ide-options-query";
12+
import { useToast } from "./toasts/Toasts";
13+
import { useFeatureFlag } from "../data/featureflag-query";
1214

1315
interface SelectIDEComponentProps {
1416
selectedIdeOption?: string;
@@ -49,6 +51,8 @@ export default function SelectIDEComponent({
4951
setError,
5052
onSelectionChange,
5153
}: SelectIDEComponentProps) {
54+
const toaster = useToast();
55+
const isLocalSSHProxyEnabled = useFeatureFlag("gitpod_desktop_use_local_ssh_proxy");
5256
const { data: ideOptions, isLoading: ideOptionsLoading } = useIDEOptions();
5357

5458
const options = useMemo(() => (ideOptions ? sortedIdeOptions(ideOptions) : undefined), [ideOptions]);
@@ -83,6 +87,38 @@ export default function SelectIDEComponent({
8387
const internalOnSelectionChange = (id: string) => {
8488
const { ide, useLatest } = parseId(id);
8589
onSelectionChange(ide, useLatest);
90+
if (ide === "code-desktop" && isLocalSSHProxyEnabled) {
91+
toaster.toast(
92+
{
93+
message: (
94+
<div>
95+
Choosing VS Code for Desktop will add a single entry to your local SSH configuration. Gitpod
96+
won't interfere with your existing SSH configurations.&nbsp;&middot;&nbsp;
97+
<a
98+
className="gp-link"
99+
href="https://www.gitpod.io/docs/references/ides-and-editors/vscode#connecting-to-vs-code-desktop"
100+
target="_blank"
101+
rel="noreferrer"
102+
>
103+
Learn more
104+
</a>
105+
&nbsp;&middot;&nbsp;
106+
<a
107+
className="gp-link"
108+
href="https://github.com/gitpod-io/gitpod/issues/18109"
109+
target="_blank"
110+
rel="noreferrer"
111+
>
112+
Send feedback
113+
</a>
114+
</div>
115+
),
116+
},
117+
{
118+
duration: 20000,
119+
},
120+
);
121+
}
86122
if (setError) {
87123
setError(undefined);
88124
}

components/dashboard/src/data/workspaces/create-workspace-mutation.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,6 @@ export const useCreateWorkspaceMutation = () => {
2222
onError: (error) => {
2323
setIsStarting(false);
2424
},
25-
onSuccess: (result) => {
26-
if (result && result.createdWorkspaceId) {
27-
// successfully started a workspace, wait a bit before we allow to start another one
28-
setTimeout(() => {
29-
setIsStarting(false);
30-
}, 4000);
31-
} else {
32-
setIsStarting(false);
33-
}
34-
},
3525
});
3626
return {
3727
createWorkspace: (options: GitpodServer.CreateWorkspaceOptions) => {

components/dashboard/src/start/start-workspace-options.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export namespace StartWorkspaceOptions {
4343
}
4444
}
4545
if (params.get(StartWorkspaceOptions.AUTOSTART)) {
46-
options.autostart = params.get(StartWorkspaceOptions.AUTOSTART) === "true";
46+
options.autostart = params.get(StartWorkspaceOptions.AUTOSTART) !== "false";
4747
}
4848
return options;
4949
}
@@ -58,8 +58,8 @@ export namespace StartWorkspaceOptions {
5858
const latest = options.ideSettings.useLatestVersion;
5959
params.set(StartWorkspaceOptions.EDITOR, latest ? ide + "-latest" : ide);
6060
}
61-
if (options.autostart) {
62-
params.set(StartWorkspaceOptions.AUTOSTART, "true");
61+
if (options.autostart !== undefined) {
62+
params.set(StartWorkspaceOptions.AUTOSTART, options.autostart.toString());
6363
}
6464
return params.toString();
6565
}

components/dashboard/src/workspaces/CreateWorkspacePage.tsx

Lines changed: 43 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,33 @@ import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
1010
import { Deferred } from "@gitpod/gitpod-protocol/lib/util/deferred";
1111
import { FC, FunctionComponent, useCallback, useContext, useEffect, useMemo, useState } from "react";
1212
import { useHistory, useLocation } from "react-router";
13-
import { Link } from "react-router-dom";
13+
import Alert from "../components/Alert";
14+
import { AuthorizeGit, useNeedsGitAuthorization } from "../components/AuthorizeGit";
1415
import { Button } from "../components/Button";
16+
import { LinkButton } from "../components/LinkButton";
1517
import Modal from "../components/Modal";
1618
import RepositoryFinder from "../components/RepositoryFinder";
1719
import SelectIDEComponent from "../components/SelectIDEComponent";
1820
import SelectWorkspaceClassComponent from "../components/SelectWorkspaceClassComponent";
1921
import { UsageLimitReachedModal } from "../components/UsageLimitReachedModal";
20-
import { CheckboxInputField } from "../components/forms/CheckboxInputField";
22+
import { InputField } from "../components/forms/InputField";
2123
import { Heading1 } from "../components/typography/headings";
2224
import { useAuthProviders } from "../data/auth-providers/auth-provider-query";
2325
import { useCurrentOrg } from "../data/organizations/orgs-query";
2426
import { useListProjectsQuery } from "../data/projects/list-projects-query";
2527
import { useCreateWorkspaceMutation } from "../data/workspaces/create-workspace-mutation";
2628
import { useListWorkspacesQuery } from "../data/workspaces/list-workspaces-query";
2729
import { useWorkspaceContext } from "../data/workspaces/resolve-context-query";
30+
import { useDirtyState } from "../hooks/use-dirty-state";
2831
import { openAuthorizeWindow } from "../provider-utils";
2932
import { getGitpodService, gitpodHostUrl } from "../service/service";
3033
import { StartWorkspaceError } from "../start/StartPage";
3134
import { VerifyModal } from "../start/VerifyModal";
3235
import { StartWorkspaceOptions } from "../start/start-workspace-options";
3336
import { UserContext, useCurrentUser } from "../user-context";
3437
import { SelectAccountModal } from "../user-settings/SelectAccountModal";
35-
import { settingsPathPreferences } from "../user-settings/settings.routes";
36-
import { WorkspaceEntry } from "./WorkspaceEntry";
37-
import { AuthorizeGit, useNeedsGitAuthorization } from "../components/AuthorizeGit";
3838
import { settingsPathIntegrations } from "../user-settings/settings.routes";
39-
import { useDirtyState } from "../hooks/use-dirty-state";
40-
import { LinkButton } from "../components/LinkButton";
41-
import { InputField } from "../components/forms/InputField";
42-
import Alert from "../components/Alert";
43-
import { useFeatureFlag } from "../data/featureflag-query";
39+
import { WorkspaceEntry } from "./WorkspaceEntry";
4440

4541
export function CreateWorkspacePage() {
4642
const { user, setUser } = useContext(UserContext);
@@ -49,8 +45,14 @@ export function CreateWorkspacePage() {
4945
const workspaces = useListWorkspacesQuery({ limit: 50 });
5046
const location = useLocation();
5147
const history = useHistory();
48+
const [contextURL, setContextURL] = useState<string | undefined>(
49+
StartWorkspaceOptions.parseContextUrl(location.hash),
50+
);
5251
const props = StartWorkspaceOptions.parseSearchParams(location.search);
53-
const [autostart, setAutostart] = useState<boolean | undefined>(props.autostart);
52+
// we autostart when a contextURL is provided via the URL hash and autostart is not explicitly set to false
53+
const [autostart, setAutostart] = useState<boolean | undefined>(
54+
contextURL !== undefined && props.autostart !== false,
55+
);
5456
const createWorkspaceMutation = useCreateWorkspaceMutation();
5557

5658
const defaultLatestIde =
@@ -66,11 +68,7 @@ export function CreateWorkspacePage() {
6668
const defaultWorkspaceClass = props.workspaceClass;
6769
const [selectedWsClass, setSelectedWsClass, selectedWsClassIsDirty] = useDirtyState(defaultWorkspaceClass);
6870
const [errorWsClass, setErrorWsClass] = useState<string | undefined>(undefined);
69-
const [contextURL, setContextURL] = useState<string | undefined>(
70-
StartWorkspaceOptions.parseContextUrl(location.hash),
71-
);
7271
const workspaceContext = useWorkspaceContext(contextURL);
73-
const [rememberOptions, setRememberOptions] = useState(false);
7472
const needsGitAuthorization = useNeedsGitAuthorization();
7573

7674
const storeAutoStartOptions = useCallback(async () => {
@@ -88,24 +86,22 @@ export function CreateWorkspacePage() {
8886
// we only keep the last 20 options
8987
workspaceAutoStartOptions = workspaceAutoStartOptions.slice(-40);
9088

91-
if (rememberOptions) {
92-
workspaceAutoStartOptions.push({
93-
cloneURL,
94-
organizationId: currentOrg.id,
95-
ideSettings: {
96-
defaultIde: selectedIde,
97-
useLatestVersion: useLatestIde,
98-
},
99-
workspaceClass: selectedWsClass,
100-
});
101-
}
89+
workspaceAutoStartOptions.push({
90+
cloneURL,
91+
organizationId: currentOrg.id,
92+
ideSettings: {
93+
defaultIde: selectedIde,
94+
useLatestVersion: useLatestIde,
95+
},
96+
workspaceClass: selectedWsClass,
97+
});
10298
AdditionalUserData.set(user, {
10399
workspaceAutostartOptions: workspaceAutoStartOptions,
104100
});
105101
setUser(user);
106102
await getGitpodService().server.updateLoggedInUser(user);
107103
console.log("Stored autostart options", workspaceAutoStartOptions);
108-
}, [currentOrg, rememberOptions, selectedIde, selectedWsClass, setUser, useLatestIde, user, workspaceContext.data]);
104+
}, [currentOrg, selectedIde, selectedWsClass, setUser, useLatestIde, user, workspaceContext.data]);
109105

110106
// see if we have a matching project based on context url and project's repo url
111107
const project = useMemo(() => {
@@ -275,7 +271,6 @@ export function CreateWorkspacePage() {
275271
(e) => e.cloneURL === cloneURL && e.organizationId === currentOrg?.id,
276272
);
277273
if (rememberedOptions) {
278-
setRememberOptions(true);
279274
if (!selectedIdeIsDirty) {
280275
setSelectedIde(rememberedOptions.ideSettings?.defaultIde, false);
281276
setUseLatestIde(!!rememberedOptions.ideSettings?.useLatestVersion);
@@ -288,12 +283,15 @@ export function CreateWorkspacePage() {
288283
setAutostart(true);
289284
}
290285
} else {
291-
setRememberOptions(false);
292286
// reset the ide settings to the user's default IF they haven't changed it manually
293287
if (!selectedIdeIsDirty) {
294288
setSelectedIde(defaultIde, false);
295289
setUseLatestIde(defaultLatestIde);
296290
}
291+
292+
if (!selectedWsClassIsDirty) {
293+
setSelectedWsClass(defaultWorkspaceClass, false);
294+
}
297295
}
298296
// we only update the remembered options when the workspaceContext changes
299297
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -314,7 +312,14 @@ export function CreateWorkspacePage() {
314312

315313
// Derive if the continue button is disabled based on current state
316314
const continueButtonDisabled = useMemo(() => {
317-
if (workspaceContext.isLoading || !contextURL || contextURL.length === 0 || !!errorIde || !!errorWsClass) {
315+
if (
316+
createWorkspaceMutation.isStarting ||
317+
workspaceContext.isLoading ||
318+
!contextURL ||
319+
contextURL.length === 0 ||
320+
!!errorIde ||
321+
!!errorWsClass
322+
) {
318323
return true;
319324
}
320325
if (workspaceContext.error) {
@@ -327,7 +332,14 @@ export function CreateWorkspacePage() {
327332
}
328333

329334
return false;
330-
}, [contextURL, errorIde, errorWsClass, workspaceContext.error, workspaceContext.isLoading]);
335+
}, [
336+
contextURL,
337+
createWorkspaceMutation.isStarting,
338+
errorIde,
339+
errorWsClass,
340+
workspaceContext.error,
341+
workspaceContext.isLoading,
342+
]);
331343

332344
if (SelectAccountPayload.is(selectAccountError)) {
333345
return (
@@ -419,14 +431,6 @@ export function CreateWorkspacePage() {
419431
</Button>
420432
</div>
421433

422-
{selectedIde === "code-desktop" && <LocalSSHWarning className="mx-6 mt-3 rounded-lg overflow-hidden" />}
423-
{workspaceContext.data && (
424-
<RememberOptions
425-
disabled={workspaceContext.isLoading || createWorkspaceMutation.isStarting}
426-
checked={rememberOptions}
427-
onChange={setRememberOptions}
428-
/>
429-
)}
430434
{existingWorkspaces.length > 0 && !createWorkspaceMutation.isStarting && (
431435
<div className="w-full flex flex-col justify-end px-6">
432436
<p className="mt-6 text-center text-base">Running workspaces on this revision</p>
@@ -448,67 +452,6 @@ export function CreateWorkspacePage() {
448452
);
449453
}
450454

451-
function LocalSSHWarning(props: { className: string }) {
452-
const isLocalSSHProxyEnabled = useFeatureFlag("gitpod_desktop_use_local_ssh_proxy");
453-
454-
if (!isLocalSSHProxyEnabled) {
455-
return null;
456-
}
457-
458-
return (
459-
<div className={props.className}>
460-
<Alert light className="bg-gray-100 dark:bg-gray-800" type="info">
461-
Choosing VS Code for Desktop will add a single entry to your local SSH configuration. Gitpod won't
462-
interfere with your existing SSH configurations.&nbsp;
463-
<a
464-
className="gp-link"
465-
href="https://www.gitpod.io/docs/references/ides-and-editors/vscode#connecting-to-vs-code-desktop"
466-
target="_blank"
467-
rel="noreferrer"
468-
>
469-
Learn more
470-
</a>
471-
&nbsp;&middot;&nbsp;
472-
<a
473-
className="gp-link"
474-
href="https://github.com/gitpod-io/gitpod/issues/18109"
475-
target="_blank"
476-
rel="noreferrer"
477-
>
478-
Send feedback
479-
</a>
480-
</Alert>
481-
</div>
482-
);
483-
}
484-
485-
function RememberOptions(params: { disabled?: boolean; checked: boolean; onChange: (checked: boolean) => void }) {
486-
const { disabled, checked, onChange } = params;
487-
488-
return (
489-
<>
490-
<div className={"w-full flex justify-center mt-3 px-8 mx-2"}>
491-
<CheckboxInputField
492-
label="Autostart with these options for this repository."
493-
checked={checked}
494-
disabled={disabled}
495-
topMargin={false}
496-
onChange={onChange}
497-
/>
498-
</div>
499-
<div className={"w-full flex justify-center px-8 mx-2"}>
500-
<p className="text-gray-400 dark:text-gray-500 text-sm">
501-
Don't worry, you can reset this anytime in your{" "}
502-
<Link to={settingsPathPreferences} className="gp-link">
503-
preferences
504-
</Link>
505-
.
506-
</p>
507-
</div>
508-
</>
509-
);
510-
}
511-
512455
function tryAuthorize(host: string, scopes?: string[]): Promise<SelectAccountPayload | undefined> {
513456
const result = new Deferred<SelectAccountPayload | undefined>();
514457
openAuthorizeWindow({

0 commit comments

Comments
 (0)