6
6
7
7
import { IDEOption , IDEOptions } from "@gitpod/gitpod-protocol/lib/ide-protocol" ;
8
8
import { useContext , useEffect , useState } from "react" ;
9
- import CheckBox from "../components/CheckBox" ;
10
9
import InfoBox from "../components/InfoBox" ;
11
10
import { PageWithSubMenu } from "../components/PageWithSubMenu" ;
12
11
import PillLabel from "../components/PillLabel" ;
@@ -19,6 +18,15 @@ import settingsMenu from "./settings-menu";
19
18
20
19
type Theme = 'light' | 'dark' | 'system' ;
21
20
21
+ const DesktopNoneId = "none"
22
+ const DesktopNone : IDEOption = {
23
+ "image" : "" ,
24
+ "logo" : "" ,
25
+ "orderKey" : "-1" ,
26
+ "title" : "None" ,
27
+ "type" : "desktop"
28
+ }
29
+
22
30
export default function Preferences ( ) {
23
31
const { user } = useContext ( UserContext ) ;
24
32
const { setIsDark } = useContext ( ThemeContext ) ;
@@ -29,6 +37,7 @@ export default function Preferences() {
29
37
const settings = additionalData . ideSettings || { } ;
30
38
settings . defaultIde = value ;
31
39
additionalData . ideSettings = settings ;
40
+ let useDesktopIde = defaultDesktopIde !== DesktopNoneId ;
32
41
getGitpodService ( ) . server . trackEvent ( {
33
42
event : "ide_configuration_changed" ,
34
43
properties : {
@@ -47,42 +56,25 @@ export default function Preferences() {
47
56
const settings = additionalData . ideSettings || { } ;
48
57
settings . defaultDesktopIde = value ;
49
58
additionalData . ideSettings = settings ;
59
+ let useDesktopIde = value !== DesktopNoneId ;
60
+ settings . useDesktopIde = useDesktopIde ;
50
61
getGitpodService ( ) . server . trackEvent ( {
51
62
event : "ide_configuration_changed" ,
52
63
properties : {
53
64
useDesktopIde,
54
65
defaultIde,
55
- defaultDesktopIde : value
66
+ defaultDesktopIde : useDesktopIde ? value : undefined
56
67
} ,
57
68
} ) ;
58
69
await getGitpodService ( ) . server . updateLoggedInUser ( { additionalData } ) ;
59
70
setDefaultDesktopIde ( value ) ;
60
71
}
61
72
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
-
82
73
const [ ideOptions , setIdeOptions ] = useState < IDEOptions | undefined > ( undefined ) ;
83
74
useEffect ( ( ) => {
84
75
( async ( ) => {
85
76
const ideopts = await getGitpodService ( ) . server . getIDEOptions ( ) ;
77
+ ideopts . options [ DesktopNoneId ] = DesktopNone ;
86
78
setIdeOptions ( ideopts ) ;
87
79
if ( ! ( defaultIde ) ) {
88
80
setDefaultIde ( ideopts . defaultIde ) ;
@@ -118,50 +110,47 @@ export default function Preferences() {
118
110
return < div >
119
111
< PageWithSubMenu subMenu = { settingsMenu } title = 'Preferences' subtitle = 'Configure user preferences.' >
120
112
{ 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 ) } />
113
+ { browserIdeOptions && < >
114
+ < h3 > Default Browser Editor</ h3 >
115
+ < p className = "text-base text-gray-500 dark:text-gray-400" > Choose which IDE you want to use.</ p >
116
+ < div className = "my-4 gap-4 flex flex-wrap" >
117
+ {
118
+ browserIdeOptions . map ( ( [ id , option ] ) => {
119
+ const selected = defaultIde === id ;
120
+ const onSelect = ( ) => actuallySetDefaultIde ( id ) ;
121
+ return renderIdeOption ( option , selected , onSelect ) ;
122
+ } )
123
+ }
144
124
</ 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 >
125
+ { ideOptions . options [ defaultIde ] . notes &&
126
+ < InfoBox className = "my-5 max-w-2xl" > < ul >
127
+ { ideOptions . options [ defaultIde ] . notes ?. map ( ( x , idx ) => < li className = { idx > 0 ? "mt-2" : "" } > { x } </ li > ) }
128
+ </ ul > </ InfoBox >
129
+ }
130
+ </ > }
131
+ { desktopIdeOptions && < >
132
+ < h3 className = "mt-12" > Default Desktop Editor</ h3 >
133
+ < p className = "text-base text-gray-500 dark:text-gray-400" > Open new workspaces with your preferred choice of desktop editor. Whilst using a desktop editor,< br /> you can also work concurrently via the browser editor.</ p >
134
+ < div className = "my-4 gap-4 flex flex-wrap" >
135
+ {
136
+ desktopIdeOptions . map ( ( [ id , option ] ) => {
137
+ let selected = defaultDesktopIde === id ;
138
+ const onSelect = ( ) => actuallySetDefaultDesktopIde ( id ) ;
139
+ if ( id === DesktopNoneId ) {
140
+ selected = defaultDesktopIde === DesktopNoneId
141
+ }
142
+ return renderIdeOption ( option , selected , onSelect ) ;
143
+ } )
160
144
}
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
- </ > }
145
+ </ div >
146
+ { ideOptions . options [ defaultDesktopIde ] . notes &&
147
+ < InfoBox className = "my-5 max-w-2xl" > < ul >
148
+ { ideOptions . options [ defaultDesktopIde ] . notes ?. map ( ( x , idx ) => < li className = { idx > 0 ? "mt-2" : "" } > { x } </ li > ) }
149
+ </ ul > </ InfoBox >
150
+ }
151
+ < p className = "text-left w-full text-gray-500" >
152
+ 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 >
153
+ </ p >
165
154
</ > }
166
155
</ > }
167
156
< h3 className = "mt-12" > Theme</ h3 >
@@ -201,6 +190,7 @@ export default function Preferences() {
201
190
}
202
191
203
192
function orderedIdeOptions ( ideOptions : IDEOptions , type : "browser" | "desktop" ) {
193
+ // TODO: Maybe convert orderKey to number?
204
194
return Object . entries ( ideOptions . options )
205
195
. filter ( ( [ _ , x ] ) => x . type === type && ! x . hidden )
206
196
. sort ( ( a , b ) => {
@@ -213,8 +203,12 @@ function orderedIdeOptions(ideOptions: IDEOptions, type: "browser" | "desktop")
213
203
function renderIdeOption ( option : IDEOption , selected : boolean , onSelect : ( ) => void ) : JSX . Element {
214
204
const card = < SelectableCard className = "w-36 h-40" title = { option . title } selected = { selected } onClick = { onSelect } >
215
205
< div className = "flex justify-center mt-3" >
216
- < img className = "w-16 filter-grayscale self-center"
217
- src = { option . logo } alt = "logo" />
206
+ < div className = "w-16 h-16 text-center" >
207
+ { option . logo && option . logo . length > 0 && < >
208
+ < img className = "w-16 filter-grayscale self-center"
209
+ src = { option . logo } alt = "logo" />
210
+ </ > }
211
+ </ div >
218
212
</ div >
219
213
{ 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 > : < > </ > }
220
214
</ SelectableCard > ;
0 commit comments