Skip to content

Commit 4cc2753

Browse files
authored
Add ui and docs for port (codesandbox#3193)
* add ui and docs for port * Update 3-configuration.md * improve clarity
1 parent a24d04f commit 4cc2753

File tree

2 files changed

+122
-95
lines changed

2 files changed

+122
-95
lines changed

packages/common/src/templates/configuration/sandbox/ui.tsx

Lines changed: 115 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from 'react';
22
import sortBy from 'lodash/sortBy';
3-
43
import * as templates from '../../../templates';
54
import Template from '../../../templates/template';
65

@@ -12,128 +11,154 @@ import {
1211
} from '../elements';
1312
import { ConfigurationUIProps } from '../types';
1413

15-
export class ConfigWizard extends React.Component<ConfigurationUIProps> {
16-
bindValue = (
14+
export const ConfigWizard = (props: ConfigurationUIProps) => {
15+
const bindValue = (
1716
file: Object,
1817
property: string,
1918
defaultValue?: any
20-
): { value: any; setValue: (p: any) => void } => ({
19+
): {
20+
value: any;
21+
setValue: (p: any) => void;
22+
} => ({
2123
value: file[property] || defaultValue,
2224
setValue: (value: any) => {
23-
const code = JSON.stringify(
25+
let code = JSON.stringify(
2426
{
2527
...file,
2628
[property]: value,
2729
},
2830
null,
2931
2
3032
);
31-
this.props.updateFile(code);
33+
if (property.includes('.')) {
34+
const children = property.split('.');
35+
code = JSON.stringify(
36+
{
37+
...file,
38+
[children[0]]: {
39+
[children[1]]: value,
40+
},
41+
},
42+
null,
43+
2
44+
);
45+
}
46+
47+
return props.updateFile(code);
3248
},
3349
});
3450

35-
render() {
36-
const { file, sandbox } = this.props;
37-
38-
let parsedFile;
39-
let error;
40-
try {
41-
parsedFile = JSON.parse(file);
42-
} catch (e) {
43-
error = e;
44-
}
45-
46-
if (error) {
47-
return <div>Problem parsing sandbox.config.json: {error.message}</div>;
48-
}
49-
50-
if (!parsedFile) {
51-
return <div>Could not parse sandbox.config.json</div>;
52-
}
53-
54-
const currentTemplate = templates.default(sandbox.template);
55-
56-
// $FlowIssue: Can't detect difference between filter/no-filter
57-
const possibleTemplates: Array<Template> = Object.keys(templates)
58-
.filter(t => t !== 'default')
59-
.map(n => templates[n]);
60-
61-
const templateOptions = sortBy(
62-
possibleTemplates.filter(
63-
template =>
64-
template.isServer === currentTemplate.isServer &&
65-
template.showOnHomePage
66-
),
67-
template => template.niceName
68-
).map(template => template.name);
69-
70-
const templateNameMap = {};
71-
possibleTemplates.forEach(template => {
72-
templateNameMap[template.name] = template.niceName;
73-
});
74-
75-
return (
76-
<div>
77-
<PaddedConfig>
78-
<ConfigItem>
79-
<PaddedPreference
80-
title="Infinite Loop Protection"
81-
type="boolean"
82-
{...this.bindValue(parsedFile, 'infiniteLoopProtection')}
83-
/>
84-
</ConfigItem>
85-
<ConfigDescription>
86-
Whether we should stop execution of the code when we detect an
87-
infinite loop.
88-
</ConfigDescription>
89-
</PaddedConfig>
51+
const { file, sandbox } = props;
9052

91-
<PaddedConfig>
92-
<ConfigItem>
93-
<PaddedPreference
94-
title="Hard Reload on Change"
95-
type="boolean"
96-
{...this.bindValue(parsedFile, 'hardReloadOnChange')}
97-
/>
98-
</ConfigItem>
99-
<ConfigDescription>
100-
Force refresh the sandbox for a change. This is helpful for
101-
sandboxes with global state, like intervals.
102-
</ConfigDescription>
103-
</PaddedConfig>
53+
let parsedFile;
54+
let error;
55+
try {
56+
parsedFile = JSON.parse(file);
57+
} catch (e) {
58+
error = e;
59+
}
60+
61+
if (error) {
62+
return <div>Problem parsing sandbox.config.json: {error.message}</div>;
63+
}
64+
65+
if (!parsedFile) {
66+
return <div>Could not parse sandbox.config.json</div>;
67+
}
10468

105-
{/* <PaddedConfig>
69+
const currentTemplate = templates.default(sandbox.template);
70+
71+
const possibleTemplates: Array<Template> = Object.keys(templates)
72+
.filter(t => t !== 'default')
73+
.map(n => templates[n]);
74+
75+
const templateOptions = sortBy(
76+
possibleTemplates.filter(
77+
template =>
78+
template.isServer === currentTemplate.isServer &&
79+
template.showOnHomePage
80+
),
81+
template => template.niceName
82+
).map(template => template.name);
83+
84+
const templateNameMap = {};
85+
possibleTemplates.forEach(template => {
86+
templateNameMap[template.name] = template.niceName;
87+
});
88+
89+
return (
90+
<div>
91+
<PaddedConfig>
92+
<ConfigItem>
93+
<PaddedPreference
94+
title="Infinite Loop Protection"
95+
type="boolean"
96+
{...bindValue(parsedFile, 'infiniteLoopProtection')}
97+
/>
98+
</ConfigItem>
99+
<ConfigDescription>
100+
Whether we should stop execution of the code when we detect an
101+
infinite loop.
102+
</ConfigDescription>
103+
</PaddedConfig>
104+
105+
<PaddedConfig>
106+
<ConfigItem>
107+
<PaddedPreference
108+
title="Hard Reload on Change"
109+
type="boolean"
110+
{...bindValue(parsedFile, 'hardReloadOnChange')}
111+
/>
112+
</ConfigItem>
113+
<ConfigDescription>
114+
Force refresh the sandbox for a change. This is helpful for sandboxes
115+
with global state, like intervals.
116+
</ConfigDescription>
117+
</PaddedConfig>
118+
119+
{/* <PaddedConfig>
106120
<ConfigItem>
107121
<PaddedPreference
108122
title="Default View"
109123
type="dropdown"
110124
options={['browser', 'console', 'tests']}
111-
{...this.bindValue(parsedFile, 'view')}
125+
{...bindValue(parsedFile, 'view')}
112126
/>
113127
</ConfigItem>
114128
<ConfigDescription>
115129
Which view to show in the preview by default.
116130
</ConfigDescription>
117131
</PaddedConfig> */}
118132

133+
<PaddedConfig>
134+
<ConfigItem>
135+
<PaddedPreference
136+
title="Template"
137+
type="dropdown"
138+
options={templateOptions}
139+
mapName={name => templateNameMap[name]}
140+
{...bindValue(parsedFile, 'template', currentTemplate.name)}
141+
/>
142+
</ConfigItem>
143+
<ConfigDescription>
144+
Which template to use for this sandbox.
145+
</ConfigDescription>
146+
</PaddedConfig>
147+
{currentTemplate.isServer ? (
119148
<PaddedConfig>
120-
<ConfigItem>
121-
<PaddedPreference
122-
title="Template"
123-
type="dropdown"
124-
options={templateOptions}
125-
mapName={name => templateNameMap[name]}
126-
{...this.bindValue(parsedFile, 'template', currentTemplate.name)}
127-
/>
128-
</ConfigItem>
149+
<PaddedPreference
150+
title="Port"
151+
type="number"
152+
{...bindValue(parsedFile, 'container.port')}
153+
/>
129154
<ConfigDescription>
130-
Which template to use for this sandbox.
155+
What is the main port of your application. Values from 1024 to 65535
131156
</ConfigDescription>
132157
</PaddedConfig>
133-
</div>
134-
);
135-
}
136-
}
158+
) : null}
159+
</div>
160+
);
161+
};
137162

138163
export default {
139164
ConfigWizard,

packages/homepage/content/docs/3-configuration.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ configuration file based on its state.
3030
A sandbox can be configured too, you can do this with `sandbox.config.json`. We
3131
support these options:
3232

33-
| Option | Description | Possible Values | Default Value |
34-
| ------------------------ | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- |
35-
| `infiniteLoopProtection` | Whether we should throw an error if we detect an infinite loop | `true`/`false` | `true` |
36-
| `hardReloadOnChange` | Whether we should refresh the sandbox page on every change, good for sandboxes with global state. | `true`/`false` | `false` |
37-
| `template` | Which sandbox template to use | [see here](https://github.com/codesandbox-app/codesandbox-importers/blob/master/packages/types/index.d.ts#L24-L39) | smart detection, w/ fallback to `create-react-app` |
33+
| Option | Description | Possible Values | Default Value |
34+
| ------------------------ | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- |
35+
| `infiniteLoopProtection` | Whether we should throw an error if we detect an infinite loop | `true`/`false` | `true` |
36+
| `hardReloadOnChange` | Whether we should refresh the sandbox page on every change, good for sandboxes with global state. | `true`/`false` | `false` |
37+
| `template` | Which sandbox template to use | [see here](https://github.com/codesandbox-app/codesandbox-importers/blob/master/packages/types/index.d.ts#L24-L39) | smart detection, w/ fallback to `create-react-app` |
38+
| `container` | The container object contains the configurable port option, for example: `container: { port: 3212}` |
39+
| `port` | The main port which the browser window listens to | 1024 - 65535 | First opened port inside the container. |

0 commit comments

Comments
 (0)