Skip to content

Commit 63e3024

Browse files
mustard-mhgtsiolisjankeromnes
committed
[dashboard] update preferences page for desktop IDE's
Co-authored-by: George Tsiolis <[email protected]> Co-authored-by: Jan Keromnes <[email protected]>
1 parent bb80946 commit 63e3024

File tree

3 files changed

+76
-89
lines changed

3 files changed

+76
-89
lines changed
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading

components/dashboard/src/settings/Preferences.tsx

Lines changed: 74 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import { IDEOption, IDEOptions } from "@gitpod/gitpod-protocol/lib/ide-protocol";
88
import { useContext, useEffect, useState } from "react";
9-
import CheckBox from "../components/CheckBox";
109
import InfoBox from "../components/InfoBox";
1110
import { PageWithSubMenu } from "../components/PageWithSubMenu";
1211
import PillLabel from "../components/PillLabel";
@@ -16,73 +15,61 @@ import { getGitpodService } from "../service/service";
1615
import { ThemeContext } from "../theme-context";
1716
import { UserContext } from "../user-context";
1817
import settingsMenu from "./settings-menu";
18+
import IDENone from '../icons/IDENone.svg';
19+
import IDENoneDark from '../icons/IDENoneDark.svg';
1920

2021
type Theme = 'light' | 'dark' | 'system';
2122

23+
const DesktopNoneId = "none";
24+
const DesktopNone: IDEOption = {
25+
"image": "",
26+
"logo": IDENone,
27+
"orderKey": "-1",
28+
"title": "None",
29+
"type": "desktop"
30+
};
31+
2232
export default function Preferences() {
2333
const { user } = useContext(UserContext);
24-
const { setIsDark } = useContext(ThemeContext);
25-
26-
const [defaultIde, setDefaultIde] = useState<string>(user?.additionalData?.ideSettings?.defaultIde || "");
27-
const actuallySetDefaultIde = async (value: string) => {
28-
const additionalData = user?.additionalData || {};
29-
const settings = additionalData.ideSettings || {};
30-
settings.defaultIde = value;
34+
const { setIsDark, isDark } = useContext(ThemeContext);
35+
36+
const updateUserIDEInfo = async (defaultDesktopIde: string, defaultIde: string) => {
37+
const useDesktopIde = defaultDesktopIde !== DesktopNoneId;
38+
const desktopIde = useDesktopIde ? defaultDesktopIde : undefined;
39+
const additionalData = user?.additionalData ?? {};
40+
const settings = additionalData.ideSettings ?? {};
41+
settings.useDesktopIde = useDesktopIde;
42+
settings.defaultIde = defaultIde;
43+
settings.defaultDesktopIde = desktopIde;
3144
additionalData.ideSettings = settings;
3245
getGitpodService().server.trackEvent({
3346
event: "ide_configuration_changed",
3447
properties: {
3548
useDesktopIde,
36-
defaultIde: value,
37-
defaultDesktopIde: useDesktopIde ? defaultDesktopIde : undefined
49+
defaultIde,
50+
defaultDesktopIde: desktopIde
3851
},
39-
});
52+
}).then().catch(console.error);
4053
await getGitpodService().server.updateLoggedInUser({ additionalData });
54+
}
55+
56+
const [defaultIde, setDefaultIde] = useState<string>(user?.additionalData?.ideSettings?.defaultIde || "");
57+
const actuallySetDefaultIde = async (value: string) => {
58+
await updateUserIDEInfo(defaultDesktopIde, value);
4159
setDefaultIde(value);
4260
}
4361

44-
const [defaultDesktopIde, setDefaultDesktopIde] = useState<string>(user?.additionalData?.ideSettings?.defaultDesktopIde || "");
62+
const [defaultDesktopIde, setDefaultDesktopIde] = useState<string>((user?.additionalData?.ideSettings?.useDesktopIde && user?.additionalData?.ideSettings?.defaultDesktopIde) || DesktopNoneId);
4563
const actuallySetDefaultDesktopIde = async (value: string) => {
46-
const additionalData = user?.additionalData || {};
47-
const settings = additionalData.ideSettings || {};
48-
settings.defaultDesktopIde = value;
49-
additionalData.ideSettings = settings;
50-
getGitpodService().server.trackEvent({
51-
event: "ide_configuration_changed",
52-
properties: {
53-
useDesktopIde,
54-
defaultIde,
55-
defaultDesktopIde: value
56-
},
57-
});
58-
await getGitpodService().server.updateLoggedInUser({ additionalData });
64+
await updateUserIDEInfo(value, defaultIde);
5965
setDefaultDesktopIde(value);
6066
}
6167

62-
const [useDesktopIde, setUseDesktopIde] = useState<boolean>(user?.additionalData?.ideSettings?.useDesktopIde || false);
63-
const actuallySetUseDesktopIde = async (value: boolean) => {
64-
const additionalData = user?.additionalData || {};
65-
const settings = additionalData.ideSettings || {};
66-
settings.useDesktopIde = value;
67-
// Make sure that default desktop IDE is set even when the user did not explicitly select one.
68-
settings.defaultDesktopIde = defaultDesktopIde;
69-
additionalData.ideSettings = settings;
70-
getGitpodService().server.trackEvent({
71-
event: "ide_configuration_changed",
72-
properties: {
73-
useDesktopIde: value,
74-
defaultIde,
75-
defaultDesktopIde: value ? defaultDesktopIde : undefined
76-
},
77-
});
78-
await getGitpodService().server.updateLoggedInUser({ additionalData });
79-
setUseDesktopIde(value);
80-
}
81-
8268
const [ideOptions, setIdeOptions] = useState<IDEOptions | undefined>(undefined);
8369
useEffect(() => {
8470
(async () => {
8571
const ideopts = await getGitpodService().server.getIDEOptions();
72+
ideopts.options[DesktopNoneId] = DesktopNone;
8673
setIdeOptions(ideopts);
8774
if (!(defaultIde)) {
8875
setDefaultIde(ideopts.defaultIde);
@@ -117,51 +104,48 @@ export default function Preferences() {
117104

118105
return <div>
119106
<PageWithSubMenu subMenu={settingsMenu} title='Preferences' subtitle='Configure user preferences.'>
120-
{ideOptions && browserIdeOptions && <>
121-
<h3>Editor</h3>
122-
<p className="text-base text-gray-500 dark:text-gray-400">Choose which IDE you want to use.</p>
123-
<div className="my-4 space-x-4 flex">
124-
{
125-
browserIdeOptions.map(([id, option]) => {
126-
const selected = defaultIde === id;
127-
const onSelect = () => actuallySetDefaultIde(id);
128-
return renderIdeOption(option, selected, onSelect);
129-
})
130-
}
131-
</div>
132-
{ideOptions.options[defaultIde].notes &&
133-
<InfoBox className="my-5 max-w-2xl"><ul>
134-
{ideOptions.options[defaultIde].notes?.map((x, idx) => <li className={idx > 0 ? "mt-2" : ""}>{x}</li>)}
135-
</ul></InfoBox>
136-
}
137-
{desktopIdeOptions && desktopIdeOptions.length > 0 && <>
138-
<div className="mt-4 space-x-4 flex">
139-
<CheckBox
140-
title={<div>Open in Desktop IDE <PillLabel type="warn" className="font-semibold mt-2 py-0.5 px-2 self-center">Beta</PillLabel></div>}
141-
desc="Choose whether you would like to open your workspace in a desktop IDE instead."
142-
checked={useDesktopIde}
143-
onChange={(evt) => actuallySetUseDesktopIde(evt.target.checked)} />
107+
{ideOptions && <>
108+
{browserIdeOptions && <>
109+
<h3>Browser Editor</h3>
110+
<p className="text-base text-gray-500 dark:text-gray-400">Choose the default editor for opening workspaces in the browser.</p>
111+
<div className="my-4 gap-4 flex flex-wrap">
112+
{
113+
browserIdeOptions.map(([id, option]) => {
114+
const selected = defaultIde === id;
115+
const onSelect = () => actuallySetDefaultIde(id);
116+
return renderIdeOption(option, selected, onSelect);
117+
})
118+
}
144119
</div>
145-
{useDesktopIde && <>
146-
<div className="my-4 space-x-4 flex">
147-
{
148-
desktopIdeOptions.map(([id, option]) => {
149-
const selected = defaultDesktopIde === id;
150-
const onSelect = () => actuallySetDefaultDesktopIde(id);
151-
return renderIdeOption(option, selected, onSelect);
152-
})
153-
}
154-
</div>
155-
156-
{ideOptions.options[defaultDesktopIde].notes &&
157-
<InfoBox className="my-5 max-w-2xl"><ul>
158-
{ideOptions.options[defaultDesktopIde].notes?.map((x, idx) => <li className={idx > 0 ? "mt-2" : ""}>{x}</li>)}
159-
</ul></InfoBox>
120+
{ideOptions.options[defaultIde]?.notes &&
121+
<InfoBox className="my-5 max-w-2xl"><ul>
122+
{ideOptions.options[defaultIde].notes?.map((x, idx) => <li className={idx > 0 ? "mt-2" : ""}>{x}</li>)}
123+
</ul></InfoBox>
124+
}
125+
</>}
126+
{desktopIdeOptions && <>
127+
<h3 className="mt-12">Desktop Editor</h3>
128+
<p className="text-base text-gray-500 dark:text-gray-400">Optionally, choose the default desktop editor for opening workspaces.</p>
129+
<div className="my-4 gap-4 flex flex-wrap">
130+
{
131+
desktopIdeOptions.map(([id, option]) => {
132+
const selected = defaultDesktopIde === id;
133+
const onSelect = () => actuallySetDefaultDesktopIde(id);
134+
if (id === DesktopNoneId) {
135+
option.logo = isDark ? IDENoneDark : IDENone
136+
}
137+
return renderIdeOption(option, selected, onSelect);
138+
})
160139
}
161-
<p className="text-left w-full text-gray-500">
162-
The <strong>JetBrains desktop IDEs</strong> are currently in beta. <a href="https://github.com/gitpod-io/gitpod/issues/6576" target="gitpod-feedback-issue" rel="noopener" className="gp-link">Send feedback</a> · <a href="https://www.gitpod.io/docs/integrations/jetbrains" target="_blank" rel="noopener noreferrer" className="gp-link">Documentation</a>
163-
</p>
164-
</>}
140+
</div>
141+
{ideOptions.options[defaultDesktopIde]?.notes &&
142+
<InfoBox className="my-5 max-w-2xl"><ul>
143+
{ideOptions.options[defaultDesktopIde].notes?.map((x, idx) => <li className={idx > 0 ? "mt-2" : ""}>{x}</li>)}
144+
</ul></InfoBox>
145+
}
146+
<p className="text-left w-full text-gray-500">
147+
The <strong>JetBrains desktop IDEs</strong> are currently in beta. <a href="https://github.com/gitpod-io/gitpod/issues/6576" target="gitpod-feedback-issue" rel="noopener" className="gp-link">Send feedback</a> · <a href="https://www.gitpod.io/docs/integrations/jetbrains" target="_blank" rel="noopener noreferrer" className="gp-link">Documentation</a>
148+
</p>
165149
</>}
166150
</>}
167151
<h3 className="mt-12">Theme</h3>
@@ -201,6 +185,7 @@ export default function Preferences() {
201185
}
202186

203187
function orderedIdeOptions(ideOptions: IDEOptions, type: "browser" | "desktop") {
188+
// TODO: Maybe convert orderKey to number before sort?
204189
return Object.entries(ideOptions.options)
205190
.filter(([_, x]) => x.type === type && !x.hidden)
206191
.sort((a, b) => {
@@ -216,7 +201,7 @@ function renderIdeOption(option: IDEOption, selected: boolean, onSelect: () => v
216201
<img className="w-16 filter-grayscale self-center"
217202
src={option.logo} alt="logo" />
218203
</div>
219-
{option.label ? <div className={`font-semibold text-sm ${selected ? 'text-green-500' : 'text-gray-500 dark:text-gray-400'} uppercase mt-2 ml-2 px-3 py-1 self-center`}>{option.label}</div> : <></>}
204+
{option.label ? <div className={`font-semibold text-sm ${selected ? 'text-green-500' : 'text-gray-500 dark:text-gray-400'} uppercase mt-2 px-3 py-1 self-center`}>{option.label}</div> : <></>}
220205
</SelectableCard>;
221206

222207
if (option.tooltip) {

0 commit comments

Comments
 (0)