Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 4 additions & 3 deletions packages/app/src/app/overmind/namespaces/editor/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -868,9 +868,10 @@ export const updateEnvironmentVariables: AsyncAction<EnvironmentVariable> = asyn
effects.codesandboxApi.restartSandbox();
};

export const deleteEnvironmentVariable: AsyncAction<{
name: string;
}> = async ({ state, effects }, { name }) => {
export const deleteEnvironmentVariable: AsyncAction<string> = async (
{ effects, state },
name
) => {
if (!state.editor.currentSandbox) {
return;
}
Expand Down
26 changes: 11 additions & 15 deletions packages/app/src/app/overmind/namespaces/server/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const restartSandbox: Action = ({ effects }) => {
effects.executor.emit('sandbox:restart');
};

export const restartContainer: Action = ({ state, effects }) => {
export const restartContainer: Action = ({ effects, state }) => {
state.server.containerStatus = ServerContainerStatus.INITIALIZING;
effects.executor.emit('sandbox:restart-container');
};
Expand Down Expand Up @@ -117,9 +117,7 @@ export const onSSEMessage: Action<{
actions: {
primary: {
label: 'Open Browser Pane',
run: () => {
actions.server.onBrowserFromPortOpened({ port });
},
run: () => actions.server.onBrowserFromPortOpened(port),
},
},
});
Expand Down Expand Up @@ -172,16 +170,13 @@ export const onCodeSandboxAPIMessage: Action<{
};

type BrowserOptions = { title?: string; url?: string } & (
| {
port: number;
}
| { port: number }
| { url: string }
);

export const onBrowserTabOpened: Action<{
closeable?: boolean;
options?: BrowserOptions;
}> = ({ actions, state }, { options, closeable }) => {
}> = ({ actions, state }, { closeable, options }) => {
const tab: ViewTab = {
id: 'codesandbox.browser',
};
Expand All @@ -206,17 +201,18 @@ export const onBrowserTabOpened: Action<{
}
};

export const onBrowserFromPortOpened: Action<{
port: ServerPort;
}> = ({ actions }, { port }) => {
if (port.main) {
export const onBrowserFromPortOpened: Action<ServerPort> = (
{ actions },
{ hostname, main, port }
) => {
if (main) {
actions.server.onBrowserTabOpened({});
} else {
actions.server.onBrowserTabOpened({
closeable: true,
options: {
port: port.port,
url: `https://${port.hostname}`,
port,
url: `https://${hostname}`,
},
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React from 'react';
import {
Button,
Collapsible,
Text,
Element,
Button,
Stack,
Text,
} from '@codesandbox/components';
import React, { FunctionComponent } from 'react';

import { useOvermind } from 'app/overmind';

import { RestartServerIcon } from './Icons';

export const Control = () => {
export const Control: FunctionComponent = () => {
const {
actions: {
server: { restartContainer, restartSandbox },
Expand All @@ -24,21 +26,22 @@ export const Control = () => {
<Collapsible defaultOpen title="Control Container">
<Element paddingX={2}>
<Button
variant="secondary"
disabled={disconnected || containerStatus !== 'sandbox-started'}
onClick={restartSandbox}
variant="secondary"
>
<Stack gap={2} align="center">
<Stack align="center" gap={2}>
<RestartServerIcon /> <Text>Restart Sandbox</Text>
</Stack>
</Button>

<Button
marginTop={2}
variant="secondary"
disabled={disconnected || containerStatus === 'initializing'}
marginTop={2}
onClick={restartContainer}
variant="secondary"
>
<Stack gap={2} align="center">
<Stack align="center" gap={2}>
<RestartServerIcon /> <Text>Restart Server</Text>
</Stack>
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import {
Button,
Element,
FormField,
Input,
Stack,
} from '@codesandbox/components';
import React, {
FormEvent,
FunctionComponent,
KeyboardEvent,
useState,
} from 'react';

const noop = () => undefined;

type Props = {
name?: string;
onCancel?: () => void;
onSubmit: (args: { name: string; value: string }) => void;
value?: string;
};
export const VarForm: FunctionComponent<Props> = ({
name: nameProp = '',
onCancel: onCancelProp = noop,
onSubmit: onSubmitProp,
value: valueProp = '',
}) => {
const [name, setName] = useState(nameProp);
const [value, setValue] = useState(valueProp);

const onSubmit = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();

if (name && value) {
onSubmitProp({ name, value });
setName('');
setValue('');
}
};

const onCancel = ({ key }: KeyboardEvent<HTMLInputElement>) => {
if (key === 'Escape') {
onCancelProp();
}
};

return (
<form onSubmit={onSubmit}>
<Element marginTop={4}>
<FormField
direction="vertical"
hideLabel
label="Environment Variable Name"
>
<Input
onChange={({ target }) => setName(target.value)}
onKeyDown={onCancel}
placeholder="Name"
required
value={name}
/>
</FormField>
</Element>

<FormField
direction="vertical"
hideLabel
label="Environment Variable Value"
>
<Input
onChange={({ target }) => setValue(target.value)}
onKeyDown={onCancel}
placeholder="Value"
required
value={value}
/>
</FormField>

<Stack paddingX={2} marginTop={2}>
{nameProp && valueProp ? (
<Button css={{ flex: 1 }} onClick={onCancelProp} variant="link">
Cancel
</Button>
) : null}

<Button
css={{ flex: 1 }}
disabled={!name || !value}
type="submit"
variant="secondary"
>
{nameProp && valueProp ? 'Save' : 'Add Secret'}
</Button>
</Stack>
</form>
);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { useOvermind } from 'app/overmind';
import React, { useEffect, useState } from 'react';

import {
Collapsible,
Text,
Expand All @@ -9,60 +6,70 @@ import {
ListItem,
Stack,
} from '@codesandbox/components';
import { DeleteIcon, EditIcon } from './Icons';
import React, { FunctionComponent, useEffect, useState } from 'react';

import { useOvermind } from 'app/overmind';

import { DeleteIcon, EditIcon } from '../Icons';

import { VarForm } from './VarForm';

export const EnvVars = () => {
const [editMode, setEditMode] = useState(null);
export const EnvVars: FunctionComponent = () => {
const {
actions: { editor },
actions: {
editor: {
deleteEnvironmentVariable,
fetchEnvironmentVariables,
updateEnvironmentVariables,
},
},
state: {
editor: { currentSandbox },
},
} = useOvermind();
const [editMode, setEditMode] = useState(null);

useEffect(() => {
editor.fetchEnvironmentVariables();
}, [editor]);

const deleteEnv = (name: string) => {
editor.deleteEnvironmentVariable({ name });
};
fetchEnvironmentVariables();
}, [fetchEnvironmentVariables]);
const envVars = currentSandbox.environmentVariables;

return (
<Collapsible title="Secret Keys" defaultOpen>
<Collapsible defaultOpen title="Secret Keys">
<Element paddingX={2}>
<Text variant="muted" block>
<Text block variant="muted">
Secrets are available as environment variables. They are kept private
and will not be transferred between forks.
</Text>
</Element>

{envVars ? (
<List paddingTop={4}>
{Object.keys(envVars).map(keyName => (
<>
{editMode === keyName || !envVars[keyName] ? (
<VarForm
name={keyName}
value={envVars[keyName]}
onCancel={() => setEditMode(null)}
onSubmit={({ name, value }) => {
editor.updateEnvironmentVariables({ name, value });
updateEnvironmentVariables({ name, value });
setEditMode(null);
}}
value={envVars[keyName]}
/>
) : (
<ListItem justify="space-between" marginTop={editMode ? 4 : 0}>
<Text>{keyName}</Text>

<Stack gap={2}>
<EditIcon
style={{ cursor: 'pointer' }}
onClick={() => setEditMode(keyName)}
style={{ cursor: 'pointer' }}
/>

<DeleteIcon
onClick={() => deleteEnvironmentVariable(keyName)}
style={{ cursor: 'pointer' }}
onClick={() => deleteEnv(keyName)}
/>
</Stack>
</ListItem>
Expand All @@ -72,11 +79,7 @@ export const EnvVars = () => {
</List>
) : null}

<VarForm
onSubmit={({ name, value }) =>
editor.updateEnvironmentVariables({ name, value })
}
/>
<VarForm onSubmit={updateEnvironmentVariables} />
</Collapsible>
);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';
import React, { FunctionComponent, SVGProps } from 'react';

export const EditIcon = props => (
type IconProps = SVGProps<SVGSVGElement>;

export const EditIcon: FunctionComponent<IconProps> = props => (
<svg width={16} height={16} fill="none" viewBox="0 0 16 16" {...props}>
<path
fill="#757575"
Expand All @@ -9,7 +11,7 @@ export const EditIcon = props => (
</svg>
);

export const DeleteIcon = props => (
export const DeleteIcon: FunctionComponent<IconProps> = props => (
<svg width={16} height={16} fill="none" viewBox="0 0 16 16" {...props}>
<path
fill="#757575"
Expand All @@ -18,7 +20,7 @@ export const DeleteIcon = props => (
</svg>
);

export const RestartServerIcon = props => (
export const RestartServerIcon: FunctionComponent<IconProps> = props => (
<svg width={12} height={11} fill="none" viewBox="0 0 12 11" {...props}>
<path
fill="#fff"
Expand Down
Loading