diff --git a/packages/app/src/app/components/DeploymentIntegration/DeploymentIntegration.tsx b/packages/app/src/app/components/DeploymentIntegration/DeploymentIntegration.tsx new file mode 100644 index 00000000000..80fb7490167 --- /dev/null +++ b/packages/app/src/app/components/DeploymentIntegration/DeploymentIntegration.tsx @@ -0,0 +1,48 @@ +import React from 'react'; + +import { DetailInfo } from './DetailInfo'; +import { + Container, + Down, + IntegrationBlock, + Name, + Notice, + Up, +} from './elements'; + +export const DeploymentIntegration = ({ + beta = false, + children, + color, + deploy, + Icon, + light = false, + loading = false, + name, + open = true, + toggle, +}) => ( + + +
+ + + {name} + + {beta && Beta} +
+ + {open ? : } +
+ + {open ? ( + + ) : null} +
+); diff --git a/packages/app/src/app/components/DeploymentIntegration/DetailInfo/DetailInfo.tsx b/packages/app/src/app/components/DeploymentIntegration/DetailInfo/DetailInfo.tsx new file mode 100644 index 00000000000..a313c44f4e1 --- /dev/null +++ b/packages/app/src/app/components/DeploymentIntegration/DetailInfo/DetailInfo.tsx @@ -0,0 +1,17 @@ +import Margin from '@codesandbox/common/lib/components/spacing/Margin'; +import { Button } from '@codesandbox/common/lib/components/Button'; +import React from 'react'; + +import { Details, Info } from './elements'; + +export const DetailInfo = ({ info, deploy, bgColor, light, loading }) => ( +
+ + {info} + + + +
+); diff --git a/packages/app/src/app/components/DeploymentIntegration/DetailInfo/elements.js b/packages/app/src/app/components/DeploymentIntegration/DetailInfo/elements.js deleted file mode 100644 index a0536cc1338..00000000000 --- a/packages/app/src/app/components/DeploymentIntegration/DetailInfo/elements.js +++ /dev/null @@ -1,22 +0,0 @@ -import styled from 'styled-components'; - -export const Details = styled.div` - display: inline-flex; - justify-content: space-between; - align-items: center; - flex: 3; - padding: 0.75rem 1rem; - background-color: ${props => props.bgColor}; - margin-top: -1px; -`; - -export const Heading = styled.div` - color: ${props => (props.light ? 'rgba(0, 0, 0)' : 'rgba(255, 255, 255)')}; - font-size: 0.75rem; - margin-bottom: 0.25rem; -`; - -export const Info = styled.div` - font-weight: 400; - color: ${props => (props.light ? 'rgba(0, 0, 0)' : 'rgba(255, 255, 255)')}; -`; diff --git a/packages/app/src/app/components/DeploymentIntegration/DetailInfo/elements.ts b/packages/app/src/app/components/DeploymentIntegration/DetailInfo/elements.ts new file mode 100644 index 00000000000..65ca606f251 --- /dev/null +++ b/packages/app/src/app/components/DeploymentIntegration/DetailInfo/elements.ts @@ -0,0 +1,28 @@ +import styled, { css } from 'styled-components'; + +export const Details = styled.div<{ bgColor: string }>` + ${({ bgColor }) => css` + display: inline-flex; + justify-content: space-between; + align-items: center; + flex: 3; + padding: 0.75rem 1rem; + background-color: ${bgColor}; + margin-top: -1px; + `} +`; + +export const Heading = styled.div<{ light: boolean }>` + ${({ light }) => css` + color: ${light ? '#000000' : '#ffffff'}; + font-size: 0.75rem; + margin-bottom: 0.25rem; + `} +`; + +export const Info = styled.div<{ light: boolean }>` + ${({ light }) => css` + color: ${light ? '#000000' : '#ffffff'}; + font-weight: 400; + `} +`; diff --git a/packages/app/src/app/components/DeploymentIntegration/DetailInfo/index.js b/packages/app/src/app/components/DeploymentIntegration/DetailInfo/index.js deleted file mode 100644 index b4178879c12..00000000000 --- a/packages/app/src/app/components/DeploymentIntegration/DetailInfo/index.js +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import Margin from '@codesandbox/common/lib/components/spacing/Margin'; -import { Button } from '@codesandbox/common/lib/components/Button'; - -import { Details, Info } from './elements'; - -function DetailInfo({ info, deploy, bgColor, light, loading }) { - return ( -
- - {info} - - -
- ); -} - -export default DetailInfo; diff --git a/packages/app/src/app/components/DeploymentIntegration/DetailInfo/index.ts b/packages/app/src/app/components/DeploymentIntegration/DetailInfo/index.ts new file mode 100644 index 00000000000..ce08e94b82d --- /dev/null +++ b/packages/app/src/app/components/DeploymentIntegration/DetailInfo/index.ts @@ -0,0 +1 @@ +export { DetailInfo } from './DetailInfo'; diff --git a/packages/app/src/app/components/DeploymentIntegration/elements.js b/packages/app/src/app/components/DeploymentIntegration/elements.js deleted file mode 100644 index fec2bf88ca0..00000000000 --- a/packages/app/src/app/components/DeploymentIntegration/elements.js +++ /dev/null @@ -1,45 +0,0 @@ -import styled, { css } from 'styled-components'; - -export const Container = styled.div` - display: inline-flex; - border-radius: 4px; - overflow: hidden; - width: 100%; - flex-direction: column; - font-size: 0.875rem; - - color: ${props => - props.light || props.theme.light ? 'rgba(0, 0, 0)' : 'rgba(255, 255, 255)'}; - - ${props => - props.loading && - css` - opacity: 0.5; - pointer-events: none; - `}; -`; - -export const IntegrationBlock = styled.div` - display: inline-flex; - align-items: center; - cursor: pointer; - box-sizing: border-box; - background-color: ${props => props.bgColor}; - flex: 1; - color: white; - padding: 0.75em 0.75em; - min-height: 45px; - font-size: 1em; - justify-content: space-between; - - > div { - display: flex; - align-items: center; - } -`; - -export const Name = styled.span` - margin-left: 0.75em; - font-size: 1.375em; - color: ${props => (props.light ? 'rgba(0, 0, 0)' : 'rgba(255, 255, 255)')}; -`; diff --git a/packages/app/src/app/components/DeploymentIntegration/elements.ts b/packages/app/src/app/components/DeploymentIntegration/elements.ts new file mode 100644 index 00000000000..c7a6b7cfc1a --- /dev/null +++ b/packages/app/src/app/components/DeploymentIntegration/elements.ts @@ -0,0 +1,68 @@ +import BaseNotice from '@codesandbox/common/lib/components/Notice'; +import BaseDown from 'react-icons/lib/fa/angle-down'; +import BaseUp from 'react-icons/lib/fa/angle-up'; +import styled, { css } from 'styled-components'; + +export const Container = styled.div` + ${({ theme }) => css` + display: inline-flex; + border-radius: 4px; + overflow: hidden; + width: 100%; + flex-direction: column; + font-size: 0.875rem; + + color: ${theme.light ? '#000000' : '#ffffff'}; + `} +`; + +export const Down = styled(BaseDown)<{ light: boolean }>` + ${({ light }) => css` + fill: ${light ? '#000000' : '#ffffff'}; + cursor: pointer; + width: 1.5rem; + height: auto; + `} +`; + +export const IntegrationBlock = styled.div<{ bgColor: string }>` + ${({ bgColor }) => css` + display: inline-flex; + align-items: center; + cursor: pointer; + box-sizing: border-box; + background-color: ${bgColor}; + flex: 1; + color: white; + padding: 0.75em 0.75em; + min-height: 45px; + font-size: 1em; + justify-content: space-between; + + > div { + display: flex; + align-items: center; + } + `} +`; + +export const Name = styled.span<{ light: boolean }>` + ${({ light }) => css` + margin-left: 0.75em; + font-size: 1.375em; + color: ${light ? '#000000' : '#ffffff'}; + `} +`; + +export const Notice = styled(BaseNotice)` + margin-left: 0.7rem; +`; + +export const Up = styled(BaseUp)<{ light: boolean }>` + ${({ light }) => css` + fill: ${light ? '#000000' : '#ffffff'}; + cursor: pointer; + width: 1.5rem; + height: auto; + `} +`; diff --git a/packages/app/src/app/components/DeploymentIntegration/index.js b/packages/app/src/app/components/DeploymentIntegration/index.js deleted file mode 100644 index b50e5ab9dee..00000000000 --- a/packages/app/src/app/components/DeploymentIntegration/index.js +++ /dev/null @@ -1,67 +0,0 @@ -import React from 'react'; -import Down from 'react-icons/lib/fa/angle-down'; -import Up from 'react-icons/lib/fa/angle-up'; -import Notice from '@codesandbox/common/lib/components/Notice'; -import DetailInfo from './DetailInfo'; -import { Container, IntegrationBlock, Name } from './elements'; - -const Integration = ({ - light, - Icon, - name, - deploy, - children, - loading, - beta, - color, - open = true, - toggle, -}) => ( - - -
- - {name} - {beta && ( - - Beta - - )} -
- {open ? ( - - ) : ( - - )} -
- {open ? ( - - ) : null} -
-); - -export default Integration; diff --git a/packages/app/src/app/components/DeploymentIntegration/index.ts b/packages/app/src/app/components/DeploymentIntegration/index.ts new file mode 100644 index 00000000000..39a6f994236 --- /dev/null +++ b/packages/app/src/app/components/DeploymentIntegration/index.ts @@ -0,0 +1 @@ +export { DeploymentIntegration } from './DeploymentIntegration'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/index.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/index.tsx index a9ffa87f0ba..99987e33db3 100644 --- a/packages/app/src/app/pages/Sandbox/Editor/Workspace/index.tsx +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/index.tsx @@ -1,20 +1,25 @@ import VERSION from '@codesandbox/common/lib/version'; import { observer } from 'mobx-react-lite'; import React from 'react'; +// Fix css prop types in styled-components (see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31245#issuecomment-463640878) +import * as CSSProps from 'styled-components/cssprop'; // eslint-disable-line + import SocialInfo from 'app/components/SocialInfo'; import { useStore } from 'app/store'; import getWorkspaceItems, { getDisabledItems, } from 'app/store/modules/workspace/items'; + +import ConfigurationFiles from './items/ConfigurationFiles'; +import { Deployment } from './items/Deployment'; import Files from './items/Files'; import { GitHub } from './items/GitHub'; -import Server from './items/Server'; import Live from './items/Live'; import { More } from './items/More'; -import Deployment from './items/Deployment'; -import ConfigurationFiles from './items/ConfigurationFiles'; import { NotOwnedSandboxInfo } from './items/NotOwnedSandboxInfo'; import { ProjectInfo } from './items/ProjectInfo'; +import Server from './items/Server'; + import { Advertisement } from './Advertisement'; import Chat from './Chat'; import { ConnectionNotice } from './ConnectionNotice'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/index.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Deployment.tsx similarity index 63% rename from packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/index.tsx rename to packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Deployment.tsx index 86b8b20a43b..41d6c892b15 100644 --- a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/index.tsx +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Deployment.tsx @@ -1,27 +1,33 @@ -import React, { useEffect } from 'react'; import { observer } from 'mobx-react-lite'; +import React, { useEffect } from 'react'; 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(); +import { Netlify } from './Netlify'; +import { Zeit } from './Zeit'; - const showPlaceholder = - !store.editor.currentSandbox.owned || !store.isLoggedIn; +export const Deployment = observer(() => { + const { + editor: { currentSandbox }, + isLoggedIn, + } = useStore(); + const { + deployment: { getDeploys }, + } = useSignals(); + const showPlaceholder = !(currentSandbox.owned && isLoggedIn); useEffect(() => { if (!showPlaceholder) { - signals.deployment.getDeploys(); + getDeploys(); } - }, [showPlaceholder, signals]); + }, [getDeploys, showPlaceholder]); if (showPlaceholder) { - const message = store.isLoggedIn ? ( + const message = isLoggedIn ? ( <> You need to own this sandbox to deploy this sandbox to Netlify or ZEIT.{' '}

Fork this sandbox to make a deploy!

@@ -39,10 +45,10 @@ const Deployment = observer(() => { You can deploy a production version of your sandbox using one our supported providers. - - + + + + ); }); - -export default Deployment; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Elements.js b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Elements.js deleted file mode 100644 index c73e8a26046..00000000000 --- a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Elements.js +++ /dev/null @@ -1,129 +0,0 @@ -import styled, { css } from 'styled-components'; - -const mapColorToState = (state, theme) => { - const STARTING = ['DEPLOYING', 'BUILDING', 'INITIALIZING']; - const ERROR = ['DEPLOYMENT_ERROR', 'BUILD_ERROR', 'ERROR']; - const STARTED = ['BOOTED', 'READY']; - - if (STARTING.includes(state)) return '#fccb7e'; - if (ERROR.includes(state)) return theme.red; - if (STARTED.includes(state)) return theme.green; - if (state === 'FROZEN') return theme.blue; - - return theme.gray; -}; - -export const State = styled.span` - align-items: center; - display: flex; - text-transform: capitalize; - margin-bottom: 0.5rem; - - &:before { - content: ''; - display: block; - width: 10px; - height: 10px; - border-radius: 50%; - margin-right: 0.5rem; - background: ${props => mapColorToState(props.state, props.theme)}; - } -`; - -export const Deploys = styled.ul` - list-style: none; - padding: 0; - margin-top: 1rem; - flex-direction: column; - font-size: 0.875rem; - margin: 0 0.25rem; -`; - -export const Deploy = styled.li` - display: flex; - margin-bottom: 1.5rem; - flex-direction: column; -`; - -export const Name = styled.span` - font-weight: 600; - color: ${props => - props.theme.light || props.light - ? 'rgba(0, 0, 0, 0.8)' - : 'rgba(255, 255, 255, 0.8)'}; - font-size: 1rem; - margin-top: 0; - vertical-align: middle; - - span { - color: ${props => - props.theme.light || props.light - ? props.theme.background3.darken(0.5) - : props.theme.background3.lighten(0.5)}; - font-size: 12px; - margin-left: 0.5rem; - } -`; - -export const Link = styled.a` - padding: 0.25rem 0.4rem; - background-color: ${props => props.theme.secondary}; - text-decoration: none; - border: none; - font-size: 0.75rem; - color: white; - border-radius: 2px; - font-weight: 600; - margin-top: 0.75rem; - display: flex; - align-items: center; - flex-grow: 0; - max-width: 50%; - - svg { - margin-right: 10px; - } - - ${props => - props.disabled && - css` - background: ${props.theme.gray}; - pointer-events: none; - `}; - - &:disabled { - background: ${props => props.theme.gray}; - } -`; - -export const Action = Link.withComponent('button'); - -export const ButtonContainer = styled.section` - display: flex; - > *:not(:last-child) { - margin-right: 0.5rem; - } -`; - -export const DeploysWrapper = styled.div` - background: rgb(0, 0, 0); - border-radius: 4px; - font-size: 0.875rem; - color: rgba(255, 255, 255, 0.8); - padding: 0.75rem 1rem; - padding: 0.75rem 0rem; - border-top-right-radius: 0; - border-top-left-radius: 0; - margin: 0.5rem 0.75rem; - margin-top: 0; -`; - -export const Wrapper = styled.div` - opacity: 1; - ${props => - props.loading && - css` - opacity: 0.5; - pointer-events: none; - `}; -`; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify.js b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify.js deleted file mode 100644 index 2f9719c8b5a..00000000000 --- a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify.js +++ /dev/null @@ -1,206 +0,0 @@ -import React, { Component } from 'react'; -import { inject, observer } from 'mobx-react'; - -import LinkIcon from 'react-icons/lib/fa/external-link'; -import Cogs from 'react-icons/lib/fa/cogs'; -import LightningIcon from 'react-icons/lib/md/flash-on'; -import NetlifyLogo from 'app/components/NetlifyLogo'; -import DeploymentIntegration from 'app/components/DeploymentIntegration'; -import getTemplate from '@codesandbox/common/lib/templates'; -import { Button } from '@codesandbox/common/lib/components/Button'; -import { resolveDirectory } from '@codesandbox/common/lib/sandbox/modules'; -import getNetlifyConfig from 'app/utils/getNetlifyConfig'; -import { WorkspaceInputContainer, WorkspaceSubtitle } from '../../elements'; -import { - Deploys, - Deploy, - Name, - Link, - DeploysWrapper, - Wrapper, - ButtonContainer, -} from './Elements'; - -const getFunctionDir = sandbox => { - try { - return resolveDirectory( - getNetlifyConfig(sandbox).functions, - sandbox.modules, - sandbox.directories - ); - } catch (e) { - return []; - } -}; - -class NetlifyDeployment extends Component { - state = { show: false }; - - toggleNetlify = () => - this.setState(state => ({ - show: !state.show, - })); - - componentDidMount() { - this.props.signals.deployment.getNetlifyDeploys(); - } - - render() { - const { - store: { deployment, editor }, - signals, - } = this.props; - - const template = getTemplate(editor.currentSandbox.template); - const { show } = this.state; - const functionDirectory = getFunctionDir(editor.currentSandbox); - - const functions = editor.currentSandbox.modules.filter( - m => m.directoryShortid === functionDirectory.shortid - ); - return ( - template.netlify !== false && ( - - - this.toggleNetlify()} - color="#fff" - light - Icon={NetlifyLogo} - name="netlify" - beta - deploy={() => signals.deployment.deployWithNetlify()} - > - Deploy your sandbox site on{' '} - - Netlify - - - - {deployment.netlifySite && show ? ( - - Sandbox Site - - - - {deployment.netlifySite.name} - {!deployment.building &&
Building
} - {functions.length ? ( - <> - - Functions - -
- {functions.map(file => ( - - - {file.title.split('.js')[0]} - - ))} -
- - ) : null} - - - Actions - - - - {deployment.building ? ( - <> - Building... - - ) : ( - <> - Visit - - )} - - - {deployment.netlifyClaimUrl ? ( - - Claim Site - - ) : null} - - {deployment.netlifyLogs ? ( - - ) : null} -
-
-
-
- ) : null} -
- ) - ); - } -} -export default inject('signals', 'store')(observer(NetlifyDeployment)); diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/DeployButton/DeployButton.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/DeployButton/DeployButton.tsx new file mode 100644 index 00000000000..3dd64fa8fb0 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/DeployButton/DeployButton.tsx @@ -0,0 +1,37 @@ +import React from 'react'; + +import { DeploymentIntegration } from 'app/components/DeploymentIntegration'; +import NetlifyLogo from 'app/components/NetlifyLogo'; +import { useSignals, useStore } from 'app/store'; + +import { DeployButtonContainer } from '../../elements'; + +export const DeployButton = ({ isOpen, toggle }) => { + const { + deployment: { deployWithNetlify }, + } = useSignals(); + const { + deployment: { building, deploying }, + } = useStore(); + + return ( + + + Deploy your sandbox site on{' '} + + Netlify + + + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/DeployButton/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/DeployButton/index.ts new file mode 100644 index 00000000000..85f358de062 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/DeployButton/index.ts @@ -0,0 +1 @@ +export { DeployButton } from './DeployButton'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/Netlify.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/Netlify.tsx new file mode 100644 index 00000000000..627cd1073b2 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/Netlify.tsx @@ -0,0 +1,41 @@ +import getTemplate from '@codesandbox/common/lib/templates'; +import { observer } from 'mobx-react-lite'; +import React, { useEffect, useState } from 'react'; + +import { useSignals, useStore } from 'app/store'; + +import { Wrapper } from '../elements'; + +import { DeployButton } from './DeployButton'; +import { SiteInfo } from './SiteInfo'; + +export const Netlify = observer(() => { + const { + deployment: { getNetlifyDeploys }, + } = useSignals(); + const { + deployment: { deploying, netlifySite }, + editor: { currentSandbox }, + } = useStore(); + + const [isVisible, setVisible] = useState(false); + + useEffect(() => { + getNetlifyDeploys(); + }, [getNetlifyDeploys]); + + const template = getTemplate(currentSandbox.template); + + return ( + template.netlify !== false && ( + + setVisible(show => !show)} + /> + + {netlifySite && isVisible ? : null} + + ) + ); +}); diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/Actions.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/Actions.tsx new file mode 100644 index 00000000000..aefd7239f85 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/Actions.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +import { useStore } from 'app/store'; + +import { ButtonContainer } from '../../../elements'; + +import { SubTitle } from '../elements'; + +import { ClaimSiteButton } from './ClaimSiteButton'; +import { VisitSiteButton } from './VisitSiteButton'; + +export const Actions = () => { + const { + deployment: { netlifyClaimUrl }, + } = useStore(); + + return ( + <> + Actions + + + + + {netlifyClaimUrl ? : null} + + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/ClaimSiteButton/ClaimSiteButton.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/ClaimSiteButton/ClaimSiteButton.tsx new file mode 100644 index 00000000000..c04621085f3 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/ClaimSiteButton/ClaimSiteButton.tsx @@ -0,0 +1,17 @@ +import React from 'react'; + +import { useStore } from 'app/store'; + +import { Link } from '../../../../elements'; + +export const ClaimSiteButton = () => { + const { + deployment: { building, netlifyClaimUrl }, + } = useStore(); + + return ( + + Claim Site + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/ClaimSiteButton/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/ClaimSiteButton/index.ts new file mode 100644 index 00000000000..46c9f71ac31 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/ClaimSiteButton/index.ts @@ -0,0 +1 @@ +export { ClaimSiteButton } from './ClaimSiteButton'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/VisitSiteButton/VisitSiteButton.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/VisitSiteButton/VisitSiteButton.tsx new file mode 100644 index 00000000000..22c903536f3 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/VisitSiteButton/VisitSiteButton.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import LinkIcon from 'react-icons/lib/fa/external-link'; +import Cogs from 'react-icons/lib/fa/cogs'; + +import { useStore } from 'app/store'; + +import { Link } from '../../../../elements'; + +export const VisitSiteButton = () => { + const { + deployment: { building, netlifySite }, + } = useStore(); + + return ( + + {building ? ( + <> + Building... + + ) : ( + <> + Visit + + )} + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/VisitSiteButton/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/VisitSiteButton/index.ts new file mode 100644 index 00000000000..3acc92dff09 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/VisitSiteButton/index.ts @@ -0,0 +1 @@ +export { VisitSiteButton } from './VisitSiteButton'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/index.ts new file mode 100644 index 00000000000..ac0eab8d42a --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Actions/index.ts @@ -0,0 +1 @@ +export { Actions } from './Actions'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Function/Function.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Function/Function.tsx new file mode 100644 index 00000000000..43e676c6c1a --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Function/Function.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import LightningIcon from 'react-icons/lib/md/flash-on'; + +import { useStore } from 'app/store'; + +import { Link } from '../../../../elements'; + +export const Function = ({ function: { title } }) => { + const { + deployment: { + building, + netlifySite: { url: siteUrl }, + }, + } = useStore(); + + const functionName = title.split('.js')[0]; + + return ( + + + + {functionName} + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Function/elements.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Function/elements.ts new file mode 100644 index 00000000000..93ed43e001e --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Function/elements.ts @@ -0,0 +1,7 @@ +import styled from 'styled-components'; + +import { Link as BaseLink } from '../../../../elements'; + +export const Section = styled(BaseLink)` + margin-right: 0.5rem; +`; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Function/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Function/index.ts new file mode 100644 index 00000000000..4b53a265c1c --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Function/index.ts @@ -0,0 +1 @@ +export { Function } from './Function'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Functions.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Functions.tsx new file mode 100644 index 00000000000..2ce2e84c6f3 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/Functions.tsx @@ -0,0 +1,18 @@ +import React from 'react'; + +import { SubTitle } from '../elements'; + +import { Section } from './elements'; +import { Function } from './Function'; + +export const Functions = ({ functions }) => ( + <> + Functions + +
+ {functions.map(func => ( + + ))} +
+ +); diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/elements.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/elements.ts new file mode 100644 index 00000000000..c1b21402fea --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/elements.ts @@ -0,0 +1,6 @@ +import styled from 'styled-components'; + +export const Section = styled.section` + display: flex; + margin-bottom: 0.5rem; +`; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/index.ts new file mode 100644 index 00000000000..baa1aa42491 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/Functions/index.ts @@ -0,0 +1 @@ +export { Functions } from './Functions'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/SiteInfo.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/SiteInfo.tsx new file mode 100644 index 00000000000..5fa8f38ace2 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/SiteInfo.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import { observer } from 'mobx-react-lite'; + +import { useStore } from 'app/store'; +import getNetlifyConfig from 'app/utils/getNetlifyConfig'; + +import { resolveDirectory } from '@codesandbox/common/lib/sandbox/modules'; + +import { + WorkspaceInputContainer, + WorkspaceSubtitle, +} from '../../../../elements'; + +import { Deploys, Deploy, Name } from '../../elements'; + +import { Actions } from './Actions'; +import { SiteInfoWrapper } from './elements'; +import { Functions } from './Functions'; +import { ViewLogsButton } from './ViewLogsButton'; + +const getFunctionDir = sandbox => { + try { + return resolveDirectory( + getNetlifyConfig(sandbox).functions, + sandbox.modules, + sandbox.directories + ); + } catch { + return undefined; + } +}; + +export const SiteInfo = observer(() => { + const { + deployment: { building, netlifyLogs, netlifySite }, + editor: { currentSandbox }, + } = useStore(); + + const functionDirectory = getFunctionDir(currentSandbox); + const functions = functionDirectory + ? currentSandbox.modules.filter( + ({ directoryShortid }) => directoryShortid === functionDirectory.shortid + ) + : []; + + return ( + + Sandbox Site + + + + + {netlifySite.name} + + {!building &&
Building
} + + {functions.length ? : null} + + + + {netlifyLogs ? : null} +
+
+
+
+ ); +}); diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/ViewLogsButton/ViewLogsButton.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/ViewLogsButton/ViewLogsButton.tsx new file mode 100644 index 00000000000..ed96f57ef9e --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/ViewLogsButton/ViewLogsButton.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +import { useSignals } from 'app/store'; + +import { Button } from './elements'; + +export const ViewLogsButton = () => { + const { modalOpened } = useSignals(); + + return ( + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/ViewLogsButton/elements.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/ViewLogsButton/elements.ts new file mode 100644 index 00000000000..5556a81373a --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/ViewLogsButton/elements.ts @@ -0,0 +1,6 @@ +import { Button as BaseButton } from '@codesandbox/common/lib/components/Button'; +import styled from 'styled-components'; + +export const Button = styled(BaseButton)` + margin-top: 20px; +`; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/ViewLogsButton/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/ViewLogsButton/index.ts new file mode 100644 index 00000000000..79ae564896b --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/ViewLogsButton/index.ts @@ -0,0 +1 @@ +export { ViewLogsButton } from './ViewLogsButton'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/elements.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/elements.ts new file mode 100644 index 00000000000..95c5c34e044 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/elements.ts @@ -0,0 +1,13 @@ +import styled from 'styled-components'; + +import { WorkspaceSubtitle } from '../../../../elements'; + +import { DeploysContainer } from '../../elements'; + +export const SiteInfoWrapper = styled(DeploysContainer)` + background-color: #ffffff; +`; + +export const SubTitle = styled(WorkspaceSubtitle)` + padding-left: 0; +`; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/index.ts new file mode 100644 index 00000000000..8d3926e6b18 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/SiteInfo/index.ts @@ -0,0 +1 @@ +export { SiteInfo } from './SiteInfo'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/index.ts new file mode 100644 index 00000000000..c10a1d00773 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Netlify/index.ts @@ -0,0 +1 @@ +export { Netlify } from './Netlify'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit.js b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit.js deleted file mode 100644 index 5b7f6f14328..00000000000 --- a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit.js +++ /dev/null @@ -1,144 +0,0 @@ -import React, { Fragment, Component } from 'react'; -import { inject, observer } from 'mobx-react'; -import TrashIcon from 'react-icons/lib/fa/trash'; -import LinkIcon from 'react-icons/lib/fa/external-link'; -import distanceInWordsToNow from 'date-fns/distance_in_words_to_now'; -import NowLogo from 'app/components/NowLogo'; -import DeploymentIntegration from 'app/components/DeploymentIntegration'; -import ZeitIntegration from '../../../../../common/ZeitIntegration'; -import { WorkspaceInputContainer, WorkspaceSubtitle } from '../../elements'; -import { - Deploys, - Wrapper, - Deploy, - State, - Name, - Link, - Action, - ButtonContainer, - DeploysWrapper, -} from './Elements'; - -class ZeitDeployment extends Component { - state = { show: false }; - - toggleZeit = () => - this.setState(state => ({ - show: !state.show, - })); - - render() { - const { - signals, - store: { user, deployment }, - } = this.props; - - const { show } = this.state; - return user.integrations.zeit ? ( - - - this.toggleZeit()} - color="#000000" - Icon={NowLogo} - name="Now" - deploy={() => signals.deployment.deploySandboxClicked()} - > - Deploy your sandbox on{' '} - - ZEIT Now - - - - {deployment.sandboxDeploys.length && show ? ( - - Sandbox Deploys - - - {deployment.sandboxDeploys.map(deploy => ( - - - {deploy.name} - ({distanceInWordsToNow(deploy.created)} ago) - - - {deploy.state.toLowerCase()} - - {deploy.alias.length ? ( - - Aliased to{' '} - {deploy.alias.map(a => ( - - {a.alias} - - ))} - - ) : null} - - - Visit - - { - signals.deployment.setDeploymentToDelete({ - id: deploy.uid, - }); - signals.modalOpened({ - modal: 'deleteDeployment', - }); - }} - > - {deployment[`${deploy.uid}Deleting`] ? ( - 'Deleting' - ) : ( - - Delete - - )} - - {deployment.hasAlias && deploy.state === 'READY' ? ( - { - signals.deployment.aliasDeployment({ - id: deploy.uid, - }); - }} - > - {deploy.alias.length ? 'Aliased' : 'Alias'} - - ) : null} - - - ))} - - - - ) : null} - - ) : ( -
- -
- ); - } -} -export default inject('signals', 'store')(observer(ZeitDeployment)); diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/DeployButton/DeployButton.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/DeployButton/DeployButton.tsx new file mode 100644 index 00000000000..6a54b0fbcb5 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/DeployButton/DeployButton.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +import { DeploymentIntegration } from 'app/components/DeploymentIntegration'; +import NowLogo from 'app/components/NowLogo'; +import { useSignals } from 'app/store'; + +import { DeployButtonContainer } from '../../elements'; + +export const DeployButton = ({ isOpen, toggle }) => { + const { + deployment: { deploySandboxClicked }, + } = useSignals(); + + return ( + + + Deploy your sandbox on{' '} + + ZEIT Now + + + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/DeployButton/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/DeployButton/index.ts new file mode 100644 index 00000000000..85f358de062 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/DeployButton/index.ts @@ -0,0 +1 @@ +export { DeployButton } from './DeployButton'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/Actions.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/Actions.tsx new file mode 100644 index 00000000000..c6f8c42a880 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/Actions.tsx @@ -0,0 +1,27 @@ +import React from 'react'; + +import { useStore } from 'app/store'; + +import { ButtonContainer } from '../../../elements'; + +import { AliasDeploymentButton } from './AliasDeploymentButton'; +import { DeleteDeploymentButton } from './DeleteDeploymentButton'; +import { VisitDeploymentButton } from './VisitDeploymentButton'; + +export const Actions = ({ deploy }) => { + const { + deployment: { hasAlias }, + } = useStore(); + + return ( + + + + + + {hasAlias && deploy.state === 'READY' ? ( + + ) : null} + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/AliasDeploymentButton/AliasDeploymentButton.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/AliasDeploymentButton/AliasDeploymentButton.tsx new file mode 100644 index 00000000000..265675393e7 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/AliasDeploymentButton/AliasDeploymentButton.tsx @@ -0,0 +1,17 @@ +import React from 'react'; + +import { useSignals } from 'app/store'; + +import { Action } from '../../../../elements'; + +export const AliasDeploymentButton = ({ deploy: { alias, uid: id } }) => { + const { + deployment: { aliasDeployment }, + } = useSignals(); + + return ( + 0} onClick={() => aliasDeployment({ id })}> + {alias.length > 0 ? 'Aliased' : 'Alias'} + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/AliasDeploymentButton/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/AliasDeploymentButton/index.ts new file mode 100644 index 00000000000..b58b8870cdc --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/AliasDeploymentButton/index.ts @@ -0,0 +1 @@ +export { AliasDeploymentButton } from './AliasDeploymentButton'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/DeleteDeploymentButton/DeleteDeploymentButton.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/DeleteDeploymentButton/DeleteDeploymentButton.tsx new file mode 100644 index 00000000000..c6ac383992b --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/DeleteDeploymentButton/DeleteDeploymentButton.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import TrashIcon from 'react-icons/lib/fa/trash'; + +import { useSignals, useStore } from 'app/store'; + +import { Action } from '../../../../elements'; + +export const DeleteDeploymentButton = ({ id }) => { + const { + deployment: { setDeploymentToDelete }, + modalOpened, + } = useSignals(); + const { deployment } = useStore(); + + return ( + { + setDeploymentToDelete({ id }); + modalOpened({ modal: 'deleteDeployment' }); + }} + > + {deployment[`${id}Deleting`] ? ( + 'Deleting' + ) : ( + <> + Delete + + )} + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/DeleteDeploymentButton/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/DeleteDeploymentButton/index.ts new file mode 100644 index 00000000000..948b72b8c6d --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/DeleteDeploymentButton/index.ts @@ -0,0 +1 @@ +export { DeleteDeploymentButton } from './DeleteDeploymentButton'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/VisitDeploymentButton/VisitDeploymentButton.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/VisitDeploymentButton/VisitDeploymentButton.tsx new file mode 100644 index 00000000000..7c2751ec502 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/VisitDeploymentButton/VisitDeploymentButton.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import LinkIcon from 'react-icons/lib/fa/external-link'; + +import { Link } from '../../../../elements'; + +export const VisitDeploymentButton = ({ url }) => ( + + Visit + +); diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/VisitDeploymentButton/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/VisitDeploymentButton/index.ts new file mode 100644 index 00000000000..7421962c1f8 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/VisitDeploymentButton/index.ts @@ -0,0 +1 @@ +export { VisitDeploymentButton } from './VisitDeploymentButton'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/index.ts new file mode 100644 index 00000000000..ac0eab8d42a --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Actions/index.ts @@ -0,0 +1 @@ +export { Actions } from './Actions'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Alias/Alias.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Alias/Alias.tsx new file mode 100644 index 00000000000..d4005af3547 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Alias/Alias.tsx @@ -0,0 +1,12 @@ +import React from 'react'; + +export const Alias = ({ alias: aliases }) => ( + + Aliased to{' '} + {aliases.map(({ alias }) => ( + + {alias} + + ))} + +); diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Alias/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Alias/index.ts new file mode 100644 index 00000000000..b24935ecbb0 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Alias/index.ts @@ -0,0 +1 @@ +export { Alias } from './Alias'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Deploys.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Deploys.tsx new file mode 100644 index 00000000000..be79030d2f6 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/Deploys.tsx @@ -0,0 +1,52 @@ +import distanceInWordsToNow from 'date-fns/distance_in_words_to_now'; +import React from 'react'; + +import { useStore } from 'app/store'; + +import { + WorkspaceInputContainer, + WorkspaceSubtitle, +} from '../../../../elements'; + +import { + Deploy, + Deploys as DeploysWrapper, + DeploysContainer, + Name, + State, +} from '../../elements'; + +import { Actions } from './Actions'; +import { Alias } from './Alias'; + +export const Deploys = () => { + const { + deployment: { sandboxDeploys }, + } = useStore(); + + return ( + + Sandbox Deploys + + + + {sandboxDeploys.map(deploy => ( + + + {deploy.name} + + {`(${distanceInWordsToNow(deploy.created)} ago)`} + + + {deploy.state.toLowerCase()} + + {deploy.alias.length > 0 ? : null} + + + + ))} + + + + ); +}; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/index.ts new file mode 100644 index 00000000000..9f86e62fc6e --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Deploys/index.ts @@ -0,0 +1 @@ +export { Deploys } from './Deploys'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Zeit.tsx b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Zeit.tsx new file mode 100644 index 00000000000..2d82c689301 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/Zeit.tsx @@ -0,0 +1,35 @@ +import { observer } from 'mobx-react-lite'; +import React, { useState } from 'react'; + +import ZeitIntegration from 'app/pages/common/ZeitIntegration'; +import { useStore } from 'app/store'; + +import { Wrapper } from '../elements'; + +import { DeployButton } from './DeployButton'; +import { Deploys } from './Deploys'; +import { NoIntegrationWrapper } from './elements'; + +export const Zeit = observer(() => { + const { + deployment: { deploying, sandboxDeploys }, + user: { integrations }, + } = useStore(); + + const [isVisible, setVisible] = useState(false); + + return integrations.zeit ? ( + + setVisible(show => !show)} + /> + + {sandboxDeploys.length && isVisible ? : null} + + ) : ( + + + + ); +}); diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/elements.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/elements.ts new file mode 100644 index 00000000000..199de976060 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/elements.ts @@ -0,0 +1,5 @@ +import styled from 'styled-components'; + +export const NoIntegrationWrapper = styled.div` + margin: 1rem; +`; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/index.ts new file mode 100644 index 00000000000..e7df9fee5dd --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/Zeit/index.ts @@ -0,0 +1 @@ +export { Zeit } from './Zeit'; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/elements.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/elements.ts new file mode 100644 index 00000000000..0d1ace783d8 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/elements.ts @@ -0,0 +1,151 @@ +import styled, { css } from 'styled-components'; + +import { WorkspaceInputContainer } from '../../elements'; + +const mapColorToState = (state: string, theme: any) => { + const STARTING = ['DEPLOYING', 'BUILDING', 'INITIALIZING']; + const ERROR = ['DEPLOYMENT_ERROR', 'BUILD_ERROR', 'ERROR']; + const STARTED = ['BOOTED', 'READY']; + + if (STARTING.includes(state)) { + return '#FCCB7E'; + } + if (ERROR.includes(state)) { + return theme.red; + } + if (STARTED.includes(state)) { + return theme.green; + } + if (state === 'FROZEN') { + return theme.blue; + } + + return theme.gray; +}; + +export const State = styled.span<{ state: string }>` + ${({ state, theme }) => css` + align-items: center; + display: flex; + text-transform: capitalize; + margin-bottom: 0.5rem; + + &:before { + content: ''; + display: block; + width: 10px; + height: 10px; + border-radius: 50%; + margin-right: 0.5rem; + background: ${mapColorToState(state, theme)}; + } + `}; +`; + +export const Deploys = styled.ul` + list-style: none; + padding: 0; + flex-direction: column; + font-size: 0.875rem; + margin: 0 0.25rem; +`; + +export const Deploy = styled.li` + display: flex; + margin-bottom: 1.5rem; + flex-direction: column; +`; + +export const Name = styled.span<{ light?: boolean }>` + ${({ light, theme }) => css` + font-weight: 600; + color: ${theme.light || light + ? css`rgba(0, 0, 0, 0.8)` + : css`rgba(255, 255, 255, 0.8)`}; + font-size: 1rem; + margin-top: 0; + vertical-align: middle; + + span { + color: ${theme.light || light + ? theme.background3.darken(0.5) + : theme.background3.lighten(0.5)}; + font-size: 12px; + margin-left: 0.5rem; + } + `}; +`; + +const BaseLink = styled.a<{ disabled?: boolean }>` + padding: 0.25rem 0.4rem; + background-color: ${props => props.theme.secondary}; + text-decoration: none; + border: none; + font-size: 0.75rem; + color: white; + border-radius: 2px; + font-weight: 600; + margin-top: 0.75rem; + display: flex; + align-items: center; + flex-grow: 0; + max-width: 50%; + + margin-top: 0; + + svg { + margin-right: 10px; + } + + ${props => + props.disabled && + css` + background: ${props.theme.gray}; + pointer-events: none; + `}; + + &:disabled { + background: ${props => props.theme.gray}; + } +`; + +export const Link = styled(BaseLink).attrs({ + rel: 'noreferrer noopener', + target: '_blank', +})``; + +export const Action = BaseLink.withComponent('button'); + +export const ButtonContainer = styled.section` + display: flex; + + > *:not(:last-child) { + margin-right: 0.5rem; + } +`; + +export const DeploysContainer = styled.div` + background-color: #000000; + border-radius: 0 0 4px 4px; + color: rgba(255, 255, 255, 0.8); + font-size: 0.875rem; + margin: -4px 0.75rem 0.5rem; + padding: 0.75rem 0; +`; + +export const Wrapper = styled.div<{ loading: boolean }>` + ${({ loading }) => css` + opacity: 1; + + ${loading && + css` + opacity: 0.5; + pointer-events: none; + `}; + `}; +`; + +export const DeployButtonContainer = styled(WorkspaceInputContainer)` + margin-bottom: 0; + margin-top: 1rem; +`; diff --git a/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/index.ts b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/index.ts new file mode 100644 index 00000000000..74dc9ac5cad --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/Editor/Workspace/items/Deployment/index.ts @@ -0,0 +1 @@ +export { Deployment } from './Deployment'; diff --git a/packages/app/src/app/pages/common/NotFound/index.tsx b/packages/app/src/app/pages/common/NotFound/index.tsx index 1281d2149db..02aedafd356 100644 --- a/packages/app/src/app/pages/common/NotFound/index.tsx +++ b/packages/app/src/app/pages/common/NotFound/index.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { observer } from 'mobx-react-lite'; import { Button } from '@codesandbox/common/lib/components/Button'; import { newSandboxWizard } from '@codesandbox/common/lib/utils/url-generator'; @@ -29,4 +30,4 @@ const NotFound = () => { ); }; -export default NotFound; +export default observer(NotFound); diff --git a/packages/app/src/app/store/modules/deployment/actions.js b/packages/app/src/app/store/modules/deployment/actions.js index f59273e2bfb..60a4b1ca11c 100644 --- a/packages/app/src/app/store/modules/deployment/actions.js +++ b/packages/app/src/app/store/modules/deployment/actions.js @@ -313,8 +313,12 @@ export async function getDeploys({ http, path, state, props }) { const assignAlias = async d => { const alias = await deploysByID(d.uid, token, http); - // eslint-disable-next-line - d.alias = alias.aliases; + if (alias) { + // eslint-disable-next-line + d.alias = alias.aliases; + } else { + d.alias = []; + } return d; }; diff --git a/packages/app/src/app/utils/getNetlifyConfig.js b/packages/app/src/app/utils/getNetlifyConfig.js index a806da5880e..f82a7456b76 100644 --- a/packages/app/src/app/utils/getNetlifyConfig.js +++ b/packages/app/src/app/utils/getNetlifyConfig.js @@ -8,5 +8,6 @@ export default sandbox => { module.title === 'netlify.toml' && module.directoryShortid == null ) .map(m => toml(m.code))[0] || { build: {} }; + return mapKeys(netlifyConfig.build, (v, k) => k.toLowerCase()); }; diff --git a/packages/common/src/sandbox/modules.ts b/packages/common/src/sandbox/modules.ts index 97f07c3d748..1b40e135e66 100644 --- a/packages/common/src/sandbox/modules.ts +++ b/packages/common/src/sandbox/modules.ts @@ -21,7 +21,9 @@ export function resolveDirectory( directories: Array, _startdirectoryShortid: string | undefined = undefined ) { - if (!_path) return throwError(''); + if (!_path) { + return throwError(''); + } let path = _path; let startdirectoryShortid = _startdirectoryShortid; @@ -40,7 +42,9 @@ export function resolveDirectory( const foundDirectoryShortid = splitPath.reduce( (dirId: string | undefined, pathPart: string, i: number) => { // Meaning this is the last argument, so the directory - if (i === splitPath.length) return dirId; + if (i === splitPath.length) { + return dirId; + } if (pathPart === '..') { // Find the parent diff --git a/packages/homepage/package.json b/packages/homepage/package.json index a1da471497b..95809eb7525 100644 --- a/packages/homepage/package.json +++ b/packages/homepage/package.json @@ -1,5 +1,5 @@ { - "name": "codesandbox-homepage", + "name": "homepage", "description": "CodeSandbox Homepage", "private": true, "version": "1.0.0",