Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/dashboard/src/data/featureflag-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const featureFlags = {
dashboard_logging_tracing: false,
showBrowserExtensionPromotion: false,
usage_update_scheduler_duration: "15m",
enable_experimental_jbtb: false,
};

type FeatureFlags = typeof featureFlags;
Expand Down
9 changes: 8 additions & 1 deletion components/dashboard/src/service/service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,15 @@ export class IDEFrontendService implements IDEFrontendDashboardService.IServer {
const desktopLink = new URL(url);
// allow to redirect only for whitelisted trusted protocols
// IDE-69
const trustedProtocols = ["vscode:", "vscode-insiders:", "jetbrains-gateway:"];
const trustedProtocols = ["vscode:", "vscode-insiders:", "jetbrains-gateway:", "jetbrains:"];
redirect = trustedProtocols.includes(desktopLink.protocol);
if (
redirect &&
desktopLink.protocol === "jetbrains:" &&
!desktopLink.href.startsWith("jetbrains://gateway/io.gitpod.toolbox.gateway/")
) {
redirect = false;
}
} catch (e) {
console.error("invalid desktop link:", e);
}
Expand Down
44 changes: 38 additions & 6 deletions components/dashboard/src/user-settings/SelectIDE.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { useUpdateCurrentUserMutation } from "../data/current-user/update-mutati
import { converter } from "../service/public-api";
import { isOrganizationOwned } from "@gitpod/public-api-common/lib/user-utils";
import Alert from "../components/Alert";
import { useFeatureFlag } from "../data/featureflag-query";
import { IDESettingsVersion } from "@gitpod/gitpod-protocol/lib/ide-protocol";

export type IDEChangedTrackLocation = "workspace_list" | "workspace_start" | "preferences";
interface SelectIDEProps {
Expand All @@ -25,18 +27,21 @@ export default function SelectIDE(props: SelectIDEProps) {

const [defaultIde, setDefaultIde] = useState<string>(user?.editorSettings?.name || "code");
const [useLatestVersion, setUseLatestVersion] = useState<boolean>(user?.editorSettings?.version === "latest");
const [preferToolbox, setPreferToolbox] = useState<boolean>(user?.editorSettings?.preferToolbox || false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can only default on undefined

Suggested change
const [preferToolbox, setPreferToolbox] = useState<boolean>(user?.editorSettings?.preferToolbox || false);
const [preferToolbox, setPreferToolbox] = useState<boolean>(user?.editorSettings?.preferToolbox ?? false);

const [ideWarning, setIdeWarning] = useState<ReactNode | undefined>(undefined);
const enableExperimentalJBTB = useFeatureFlag("enable_experimental_jbtb");

const isOrgOwnedUser = user && isOrganizationOwned(user);

const actualUpdateUserIDEInfo = useCallback(
async (selectedIde: string, useLatestVersion: boolean) => {
async (selectedIde: string, useLatestVersion: boolean, preferToolbox: boolean) => {
// update stored autostart options to match useLatestVersion value set here
const workspaceAutostartOptions = user?.workspaceAutostartOptions?.map((o) => {
const option = converter.fromWorkspaceAutostartOption(o);

if (option.ideSettings) {
option.ideSettings.useLatestVersion = useLatestVersion;
option.ideSettings.preferToolbox = preferToolbox;
}

return option;
Expand All @@ -46,9 +51,10 @@ export default function SelectIDE(props: SelectIDEProps) {
additionalData: {
workspaceAutostartOptions,
ideSettings: {
settingVersion: "2.0",
settingVersion: IDESettingsVersion,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

defaultIde: selectedIde,
useLatestVersion: useLatestVersion,
preferToolbox: preferToolbox,
},
},
});
Expand All @@ -59,18 +65,26 @@ export default function SelectIDE(props: SelectIDEProps) {

const actuallySetDefaultIde = useCallback(
async (value: string) => {
await actualUpdateUserIDEInfo(value, useLatestVersion);
await actualUpdateUserIDEInfo(value, useLatestVersion, preferToolbox);
setDefaultIde(value);
},
[actualUpdateUserIDEInfo, useLatestVersion],
[actualUpdateUserIDEInfo, useLatestVersion, preferToolbox],
);

const actuallySetUseLatestVersion = useCallback(
async (value: boolean) => {
await actualUpdateUserIDEInfo(defaultIde, value);
await actualUpdateUserIDEInfo(defaultIde, value, preferToolbox);
setUseLatestVersion(value);
},
[actualUpdateUserIDEInfo, defaultIde],
[actualUpdateUserIDEInfo, defaultIde, preferToolbox],
);

const actuallySetPreferToolbox = useCallback(
async (value: boolean) => {
await actualUpdateUserIDEInfo(defaultIde, useLatestVersion, value);
setPreferToolbox(value);
},
[actualUpdateUserIDEInfo, defaultIde, useLatestVersion],
);

const shouldShowJetbrainsNotice = isJetbrains(defaultIde);
Expand Down Expand Up @@ -142,6 +156,24 @@ export default function SelectIDE(props: SelectIDEProps) {
checked={useLatestVersion}
onChange={(checked) => actuallySetUseLatestVersion(checked)}
/>

{enableExperimentalJBTB && (
<CheckboxInputField
label={
<span className="flex items-center gap-2">
Launch in JetBrains Toolbox{" "}
<PillLabel type="warn">
<a href="https://www.gitpod.io/docs/references/gitpod-releases">
<span className="text-xs">BETA</span>
</a>
</PillLabel>
</span>
}
hint={<span>Launch JetBrains IDEs in the JetBrains Toolbox.</span>}
checked={preferToolbox}
onChange={(checked) => actuallySetPreferToolbox(checked)}
/>
)}
</>
);
}
19 changes: 18 additions & 1 deletion components/dashboard/src/workspaces/CreateWorkspacePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ export function CreateWorkspacePage() {
props.ideSettings?.useLatestVersion !== undefined
? props.ideSettings.useLatestVersion
: user?.editorSettings?.version === "latest";
const defaultPreferToolbox = props.ideSettings?.preferToolbox ?? user?.editorSettings?.preferToolbox ?? false;
const [useLatestIde, setUseLatestIde] = useState(defaultLatestIde);
const [preferToolbox, setPreferToolbox] = useState(defaultPreferToolbox);
// Note: it has data fetching and UI rendering race between the updating of `selectedProjectId` and `selectedIde`
// We have to stored the using repositoryId locally so that we can know selectedIde is updated because if which repo
// so that it doesn't show ide error messages in middle state
Expand Down Expand Up @@ -145,6 +147,7 @@ export function CreateWorkspacePage() {
editorSettings: new EditorReference({
name: selectedIde,
version: useLatestIde ? "latest" : "stable",
preferToolbox: preferToolbox,
}),
}),
);
Expand All @@ -156,7 +159,17 @@ export function CreateWorkspacePage() {
},
});
setUser(updatedUser);
}, [updateUser, currentOrg, selectedIde, selectedWsClass, setUser, useLatestIde, user, workspaceContext.data]);
}, [
updateUser,
currentOrg,
selectedIde,
selectedWsClass,
setUser,
useLatestIde,
preferToolbox,
user,
workspaceContext.data,
]);

// see if we have a matching project based on context url and project's repo url
const project = useMemo(() => {
Expand Down Expand Up @@ -271,6 +284,7 @@ export function CreateWorkspacePage() {
contextUrlSource.editor = {
name: selectedIde,
version: useLatestIde ? "latest" : undefined,
preferToolbox: preferToolbox,
};
}
opts.source = {
Expand Down Expand Up @@ -301,6 +315,7 @@ export function CreateWorkspacePage() {
selectedWsClass,
selectedIde,
useLatestIde,
preferToolbox,
createWorkspaceMutation,
selectedProjectID,
storeAutoStartOptions,
Expand Down Expand Up @@ -358,6 +373,7 @@ export function CreateWorkspacePage() {
}
setSelectedIde(rememberedOptions.editorSettings?.name, false);
setUseLatestIde(rememberedOptions.editorSettings?.version === "latest");
setPreferToolbox(rememberedOptions.editorSettings?.preferToolbox || false);
}

if (!selectedWsClassIsDirty) {
Expand All @@ -374,6 +390,7 @@ export function CreateWorkspacePage() {
if (!selectedIdeIsDirty) {
setSelectedIde(defaultIde, false);
setUseLatestIde(defaultLatestIde);
setPreferToolbox(defaultPreferToolbox);
}
if (!selectedWsClassIsDirty) {
const projectWsClass = project?.settings?.workspaceClasses?.regular;
Expand Down
1 change: 1 addition & 0 deletions components/gitpod-protocol/go/gitpod-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2058,6 +2058,7 @@ type IDESettings struct {
UseDesktopIde bool `json:"useDesktopIde,omitempty"`
DefaultDesktopIde string `json:"defaultDesktopIde,omitempty"`
UseLatestVersion bool `json:"useLatestVersion"`
PreferToolbox bool `json:"preferToolbox"`
}

// EmailNotificationSettings is the EmailNotificationSettings message type
Expand Down
1 change: 1 addition & 0 deletions components/gitpod-protocol/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ export type IDESettings = {
settingVersion?: string;
defaultIde?: string;
useLatestVersion?: boolean;
preferToolbox?: boolean;
// DEPRECATED: Use defaultIde after `settingVersion: 2.0`, no more specialify desktop or browser.
useDesktopIde?: boolean;
// DEPRECATED: Same with useDesktopIde.
Expand Down
1 change: 1 addition & 0 deletions components/gitpod-protocol/src/workspace-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ export namespace WorkspaceInstanceRepoStatus {
export interface ConfigurationIdeConfig {
useLatest?: boolean;
ide?: string;
preferToolbox?: boolean;
}

export interface IdeSetup {
Expand Down
12 changes: 12 additions & 0 deletions components/ide-service/example-ide-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@
"If you don't see an open dialog in your browser, make sure you have the \u003ca target='_blank' class='gp-link' href='https://www.gitpod.io/docs/ides-and-editors/jetbrains-gateway#getting-started-jetbrains-gateway'\u003eJetBrains Gateway with Gitpod Plugin\u003c/a\u003e installed on your machine, and then click \u003cb\u003e${OPEN_LINK_LABEL}\u003c/b\u003e below."
]
},
"jetbrains-toolbox": {
"defaultDesktopIDE": "intellij",
"desktopIDEs": [
"intellij",
"goland",
"pycharm",
"phpstorm"
],
"installationSteps": [
"If you don't see an open dialog in your browser, make sure you have the \u003ca target='_blank' class='gp-link' href='https://www.gitpod.io/docs/ides-and-editors/jetbrains-gateway#getting-started-jetbrains-gateway'\u003eJetBrains Toolbox with Gitpod Plugin\u003c/a\u003e installed on your machine, and then click \u003cb\u003e${OPEN_LINK_LABEL}\u003c/b\u003e below."
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Draft changes, will update in the future

]
},
"vscode": {
"defaultDesktopIDE": "code-desktop",
"desktopIDEs": [
Expand Down
12 changes: 12 additions & 0 deletions components/ide-service/pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ func grpcProbe(cfg baseserver.ServerConfiguration) func() error {
type IDESettings struct {
DefaultIde string `json:"defaultIde,omitempty"`
UseLatestVersion bool `json:"useLatestVersion,omitempty"`
PreferToolbox bool `json:"preferToolbox,omitempty"`
PinnedIDEversions map[string]string `json:"pinnedIDEversions,omitempty"`
}

Expand Down Expand Up @@ -440,12 +441,22 @@ func (s *IDEServiceServer) ResolveWorkspaceConfig(ctx context.Context, req *api.

userIdeName := ""
useLatest := false
preferToolbox := false
resultingIdeName := ideConfig.IdeOptions.DefaultIde
chosenIDE := ideConfig.IdeOptions.Options[resultingIdeName]

if ideSettings != nil {
userIdeName = ideSettings.DefaultIde
useLatest = ideSettings.UseLatestVersion
preferToolbox = ideSettings.PreferToolbox
}

if preferToolbox {
preferToolboxEnv := api.EnvironmentVariable{
Name: "GITPOD_PREFER_TOOLBOX",
Value: "true",
}
resp.Envvars = append(resp.Envvars, &preferToolboxEnv)
}

if userIdeName != "" {
Expand Down Expand Up @@ -499,6 +510,7 @@ func (s *IDEServiceServer) ResolveWorkspaceConfig(ctx context.Context, req *api.
resultingIdeSettings := &IDESettings{
DefaultIde: resultingIdeName,
UseLatestVersion: useLatest,
PreferToolbox: preferToolbox,
}

err = enc.Encode(resultingIdeSettings)
Expand Down
Loading