Skip to content

Commit 7396b44

Browse files
committed
fix #2477: actually allow to select custom imag
1 parent 60a85a4 commit 7396b44

File tree

1 file changed

+60
-29
lines changed

1 file changed

+60
-29
lines changed

components/dashboard/src/components/ide-settings.tsx

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,35 @@ function isIDEAlias(ide: string | undefined): ide is IDEAlias {
2727
}
2828
type IDEKind = IDEAlias | 'image';
2929

30-
export class IDESettings extends React.Component<IDESettingsProps> {
30+
export interface IDESettingsState {
31+
value?: IDEKind
32+
image?: string
33+
}
34+
35+
export class IDESettings extends React.Component<IDESettingsProps, IDESettingsState> {
36+
37+
constructor(props: IDESettingsProps) {
38+
super(props);
39+
this.state = this.updateStateFromProps({})
40+
}
41+
42+
componentDidUpdate(prevProps: IDESettingsProps): void {
43+
if (this.props.user === prevProps.user) {
44+
return;
45+
}
46+
this.setState(state => this.updateStateFromProps(state));
47+
}
48+
49+
private updateStateFromProps(current: IDESettingsState): IDESettingsState {
50+
const defaultIde = this.props.user.additionalData?.ideSettings?.defaultIde;
51+
if (isIDEAlias(defaultIde)) {
52+
return { ...current, value: defaultIde };
53+
}
54+
if (defaultIde === undefined) {
55+
return { ...current, value: 'theia' };
56+
}
57+
return { ...current, value: 'image', image: defaultIde };
58+
}
3159

3260
render() {
3361
return <React.Fragment>
@@ -38,50 +66,53 @@ export class IDESettings extends React.Component<IDESettingsProps> {
3866
}
3967

4068
private renderRadio(label: string, value: IDEKind) {
41-
const checked = value === this.value;
42-
return <Grid item xs={12}>
43-
<FormControlLabel control={<Radio color="default" />} label={label} value={value} checked={checked} onChange={this.updateDefaultIde} />
44-
{value === 'image' && <Input value={this.image} onChange={this.updateDefaultIde} />}
45-
</Grid>;
69+
const checked = value === this.state.value;
70+
return <Grid container>
71+
<Grid item xs={1}>
72+
<FormControlLabel control={<Radio color="default" />} label={label} value={value} checked={checked} onChange={this.updateState} />
73+
</Grid>
74+
<Grid item xs={11}>
75+
{value === 'image' && this.renderImage()}
76+
</Grid>
77+
</Grid>
4678
}
4779

48-
private get value(): IDEKind {
49-
const defaultIde = this.props.user.additionalData?.ideSettings?.defaultIde;
50-
if (isIDEAlias(defaultIde)) {
51-
return defaultIde;
52-
}
53-
if (defaultIde) {
54-
return 'image';
55-
}
56-
return 'theia';
57-
}
58-
59-
private get image(): string | undefined {
60-
const defaultIde = this.props.user.additionalData?.ideSettings?.defaultIde;
61-
if (isIDEAlias(defaultIde)) {
62-
return undefined;
63-
}
64-
return defaultIde;
80+
private renderImage() {
81+
return <Input
82+
value={this.state.image}
83+
onChange={this.updateState}
84+
placeholder="Type a reference to docker image, e.g. index.docker.io/gitpod-io/theia-ide:latest"
85+
error={this.state.value === 'image' && (this.state.image === undefined || this.state.image.trim() === "")}
86+
fullWidth={true}
87+
/>;
6588
}
6689

67-
private updateDefaultIde = (event: React.ChangeEvent<HTMLInputElement>) => {
68-
let value = this.value;
69-
let image = this.image;
90+
private updateState = (event: React.ChangeEvent<HTMLInputElement>) => {
91+
const state: IDESettingsState = {}
7092
if (event.target.type === 'radio') {
71-
value = event.target.value as IDEKind;
93+
state.value = event.target.value as IDEKind;
7294
} else {
73-
image = event.target.value;
95+
state.image = event.target.value;
7496
}
97+
this.setState(state, () => this.fireStateChange());
98+
}
99+
100+
private fireStateChange(): void {
101+
const { value, image } = this.state;
75102

76103
const additionalData = (this.props.user.additionalData || {});
77104
const settings = additionalData.ideSettings || {};
78105
if (value === 'theia') {
79106
delete settings.defaultIde;
80107
} else if (value === 'image') {
81-
settings.defaultIde = image;
108+
settings.defaultIde = image || '';
82109
} else {
83110
settings.defaultIde = value;
84111
}
112+
if (settings.defaultIde?.trim() === "") {
113+
// invalid
114+
return;
115+
}
85116
additionalData.ideSettings = settings;
86117
this.props.onChange({ additionalData });
87118
}

0 commit comments

Comments
 (0)