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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Action } from 'app/overmind';
import getItems from './items';
import { Sandbox } from '@codesandbox/common/lib/types';
import getItems from './items';

export const setWorkspace: Action<Sandbox> = ({ state }, sandbox) => {
state.workspace.project.title = sandbox.title || '';
Expand Down
37 changes: 25 additions & 12 deletions packages/app/src/app/overmind/namespaces/workspace/items.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,66 @@
import getTemplate from '@codesandbox/common/lib/templates';

const PROJECT = {
interface INavigationItem {
id: string;
name: string;
hasCustomHeader?: boolean;
defaultOpen?: boolean;
}

const PROJECT: INavigationItem = {
id: 'project',
name: 'Project Info',
name: 'Sandbox Info',
};

const PROJECT_TEMPLATE: INavigationItem = {
...PROJECT,
name: 'Template Info',
};

const PROJECT_SUMMARY = {
const PROJECT_SUMMARY: INavigationItem = {
id: 'project-summary',
name: 'Sandbox Info',
hasCustomHeader: true,
};

const FILES = {
const FILES: INavigationItem = {
id: 'files',
name: 'Explorer',
hasCustomHeader: true,
defaultOpen: true,
};

const GITHUB = {
const GITHUB: INavigationItem = {
id: 'github',
name: 'GitHub',
};

const DEPLOYMENT = {
const DEPLOYMENT: INavigationItem = {
id: 'deploy',
name: 'Deployment',
};

const CONFIGURATION = {
const CONFIGURATION: INavigationItem = {
id: 'config',
name: 'Configuration Files',
};

const LIVE = {
const LIVE: INavigationItem = {
id: 'live',
name: 'Live',
};

const MORE = {
const MORE: INavigationItem = {
id: 'more',
name: 'More',
};

const SERVER = {
const SERVER: INavigationItem = {
id: 'server',
name: 'Server Control Panel',
};

export default function getItems(store) {
export default function getItems(store): INavigationItem[] {
if (
store.live.isLive &&
!(
Expand All @@ -66,7 +78,8 @@ export default function getItems(store) {
return [PROJECT_SUMMARY, CONFIGURATION, MORE];
}

const items = [PROJECT, FILES];
const isCustomTemplate = !!store.editor.currentSandbox.customTemplate;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const isCustomTemplate = !!store.editor.currentSandbox.customTemplate;
const isCustomTemplate = Boolean(store.editor.currentSandbox.customTemplate);

const items = [isCustomTemplate ? PROJECT_TEMPLATE : PROJECT, FILES];

if (store.isLoggedIn && store.editor.currentSandbox) {
const templateDef = getTemplate(store.editor.currentSandbox.template);
Expand Down
84 changes: 53 additions & 31 deletions packages/app/src/app/pages/Sandbox/Editor/Navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import FilesIcon from '-!svg-react-loader!@codesandbox/common/lib/icons/file.svg
import RocketIcon from '-!svg-react-loader!@codesandbox/common/lib/icons/rocket.svg';
// @ts-ignore
import ConfigurationIcon from '-!svg-react-loader!@codesandbox/common/lib/icons/cog.svg';
import getWorkspaceItems from 'app/store/modules/workspace/items';
import getWorkspaceItems, {
getDisabledItems,
INavigationItem,
} from 'app/store/modules/workspace/items';
import { useSignals, useStore } from 'app/store';
import { Container, IconContainer } from './elements';
import { Container, IconContainer, Separator } from './elements';
import ServerIcon from './ServerIcon';

const IDS_TO_ICONS = {
Expand All @@ -31,6 +34,42 @@ const IDS_TO_ICONS = {
server: ServerIcon,
};

interface IconProps {
item: INavigationItem;
isDisabled?: boolean;
}

const IconComponent = observer(({ item, isDisabled }: IconProps) => {
const { id, name } = item;
const store = useStore();
const {
workspace: { setWorkspaceHidden, setWorkspaceItem },
} = useSignals();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const {
workspace: { setWorkspaceHidden, setWorkspaceItem },
} = useSignals();

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Much cleaner!

const Icon = IDS_TO_ICONS[id];
const selected =
!store.workspace.workspaceHidden &&
id === store.workspace.openedWorkspaceItem;
return (
<Tooltip key={id} placement="right" content={name}>
<IconContainer
isDisabled={isDisabled}
selected={selected}
onClick={() => {
if (selected) {
setWorkspaceHidden({ hidden: true });
} else {
setWorkspaceHidden({ hidden: false });
setWorkspaceItem({ item: id });
}
}}
>
<Icon />
</IconContainer>
</Tooltip>
);
});

export const Navigation = observer(
({
topOffset,
Expand All @@ -39,39 +78,22 @@ export const Navigation = observer(
topOffset: number;
bottomOffset: number;
}) => {
const {
workspace: { setWorkspaceHidden, setWorkspaceItem },
} = useSignals();
const store = useStore();

const shownItems = getWorkspaceItems(store);
const disabledItems = getDisabledItems(store);

return (
<Container topOffset={topOffset} bottomOffset={bottomOffset}>
{getWorkspaceItems(store)
.filter(w => !w.show || w.show(store))
.map(item => {
const { id, name } = item;
const Icon = IDS_TO_ICONS[id];
const selected =
!store.workspace.workspaceHidden &&
id === store.workspace.openedWorkspaceItem;
return (
<Tooltip key={id} placement="right" content={name}>
<IconContainer
selected={selected}
onClick={() => {
if (selected) {
setWorkspaceHidden({ hidden: true });
} else {
setWorkspaceHidden({ hidden: false });
setWorkspaceItem({ item: id });
}
}}
>
<Icon />
</IconContainer>
</Tooltip>
);
})}
{shownItems.map(item => (
<IconComponent key={item.id} item={item} />
))}

<Separator />

{disabledItems.map(item => (
<IconComponent key={item.id} item={item} isDisabled />
))}
</Container>
);
}
Expand Down
62 changes: 42 additions & 20 deletions packages/app/src/app/pages/Sandbox/Editor/Navigation/elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,48 @@ export const Container = styled.div`
`}
`;

export const IconContainer = styled.div`
${({ selected, theme }: { selected: boolean; theme: any }) => css`
display: flex;
justify-content: center;
align-items: center;
transition: 0.3s ease all;
height: 3.5rem;
width: 3.5rem;
font-size: 1.875rem;
color: ${theme[`activityBar.inactiveForeground`] ||
css`rgba(255, 255, 255, 0.5)`};
cursor: pointer;
export const IconContainer = styled.div<{
selected: boolean;
isDisabled: boolean;
}>`
display: flex;
justify-content: center;
align-items: center;
transition: 0.3s ease all;
height: 3.5rem;
width: 3.5rem;
font-size: 1.875rem;
color: ${props =>
props.theme[`activityBar.inactiveForeground`] ||
css`rgba(255, 255, 255, 0.5)`};
cursor: pointer;

&:hover {
color: ${theme[`activityBar.foreground`] || css`white`};
}
&:hover {
color: ${props => props.theme[`activityBar.foreground`] || css`white`};
}

${selected &&
css`
color: ${theme[`activityBar.foreground`] || css`white`};
`};
`}
${props =>
props.selected &&
css`
color: ${props.theme[`activityBar.foreground`] || css`white`};
`};

${props =>
props.isDisabled &&
!props.selected &&
css`
opacity: 0.4;
`}
`;

export const Separator = styled.hr`
width: calc(100% - 20px);
height: 1px;
background-color: ${props =>
props.theme.light ? 'rgba(0, 0, 0, 0.2)' : 'rgba(255,255,255,0.1)'};

margin: 0.25rem 0;

outline: none;
border: none;
`;
8 changes: 6 additions & 2 deletions packages/app/src/app/pages/Sandbox/Editor/Workspace/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { observer } from 'mobx-react-lite';
import React from 'react';
import SocialInfo from 'app/components/SocialInfo';
import { useStore } from 'app/store';
import getWorkspaceItems from 'app/store/modules/workspace/items';
import getWorkspaceItems, {
getDisabledItems,
} from 'app/store/modules/workspace/items';
import Files from './items/Files';
import { GitHub } from './items/GitHub';
import Server from './items/Server';
Expand Down Expand Up @@ -56,7 +58,9 @@ const Workspace = () => {
}

const Component = workspaceTabs[activeTab];
const item = getWorkspaceItems(store).find(({ id }) => id === activeTab);
const item =
getWorkspaceItems(store).find(({ id }) => id === activeTab) ||
getDisabledItems(store).find(({ id }) => id === activeTab);

return (
<Container>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { useEffect } from 'react';
import { observer } from 'mobx-react-lite';

import { useStore, useSignals } from 'app/store';
import { Description } from '../../elements';
import ZeitDeployments from './Zeit';
import NetlifyDeployments from './Netlify';
import { More } from '../More';

const Deployment = observer(() => {
const store = useStore();
const signals = useSignals();

const showPlaceholder =
!store.editor.currentSandbox.owned || !store.isLoggedIn;

useEffect(() => {
if (!showPlaceholder) {
signals.deployment.getDeploys();
}
}, [showPlaceholder, signals]);

if (showPlaceholder) {
const message = store.isLoggedIn ? (
<>
You need to own this sandbox to deploy this sandbox to Netlify or ZEIT.{' '}
<p>Fork this sandbox to make a deploy!</p>
</>
) : (
<>You need to be signed in to deploy this sandbox to Netlify or ZEIT.</>
);

return <More message={message} id="github" />;
}

return (
<div>
<Description>
You can deploy a production version of your sandbox using one our
supported providers.
</Description>
<ZeitDeployments />
<NetlifyDeployments />
</div>
);
});

export default Deployment;
Loading