Skip to content

Commit df13fef

Browse files
authored
fix: Remove 'Create Project' button, replace with CLI prompt (#245)
For black-triangle and alpha builds, we won't be able to create projects in the UI, because they require collecting and tar'ing a set of assets associated with the project - so the CLI is going to be our entry point for creating projects. This shifts the UI to remove the 'Create Project' button, and adds a prompt to copy a command to run. __Before:__ <img width="1134" alt="image" src="https://user-images.githubusercontent.com/88213859/153534269-58dc95bd-0417-4bed-8e62-e2b6f479da61.png"> __After:__ ![2022-02-10 19 38 01](https://user-images.githubusercontent.com/88213859/153534227-d22bd786-8c43-4858-bda6-3d9d1d614711.gif)
1 parent c0d547b commit df13fef

File tree

13 files changed

+193
-27
lines changed

13 files changed

+193
-27
lines changed

site/.eslintrc.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ rules:
9292
message:
9393
"Use path imports to avoid pulling in unused modules. See:
9494
https://material-ui.com/guides/minimizing-bundle-size/"
95-
- name: "@material-ui/core/Tooltip"
96-
message: "Use the custom Tooltip on componens/Tooltip"
9795
no-storage/no-browser-storage: error
9896
no-unused-vars: "off"
9997
"object-curly-spacing": "off"

site/components/Button/CopyButton.tsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { makeStyles } from "@material-ui/core/styles"
2+
import Button from "@material-ui/core/Button"
3+
import Tooltip from "@material-ui/core/Tooltip"
4+
import Check from "@material-ui/icons/Check"
5+
import React, { useState } from "react"
6+
import { FileCopy } from "../Icons"
7+
8+
interface CopyButtonProps {
9+
text: string
10+
className?: string
11+
}
12+
13+
/**
14+
* Copy button used inside the CodeBlock component internally
15+
*/
16+
export const CopyButton: React.FC<CopyButtonProps> = ({ className = "", text }) => {
17+
const styles = useStyles()
18+
const [isCopied, setIsCopied] = useState<boolean>(false)
19+
20+
const copyToClipboard = async (): Promise<void> => {
21+
try {
22+
await window.navigator.clipboard.writeText(text)
23+
setIsCopied(true)
24+
25+
window.setTimeout(() => {
26+
setIsCopied(false)
27+
}, 1000)
28+
} catch (err) {
29+
const wrappedErr = new Error("copyToClipboard: failed to copy text to clipboard")
30+
if (err instanceof Error) {
31+
wrappedErr.stack = err.stack
32+
}
33+
console.error(wrappedErr)
34+
}
35+
}
36+
37+
return (
38+
<Tooltip title="Copy to Clipboard" placement="top">
39+
<div className={`${styles.copyButtonWrapper} ${className}`}>
40+
<Button className={styles.copyButton} onClick={copyToClipboard} size="small">
41+
{isCopied ? <Check className={styles.fileCopyIcon} /> : <FileCopy className={styles.fileCopyIcon} />}
42+
</Button>
43+
</div>
44+
</Tooltip>
45+
)
46+
}
47+
48+
const useStyles = makeStyles((theme) => ({
49+
copyButtonWrapper: {
50+
display: "flex",
51+
marginLeft: theme.spacing(1),
52+
},
53+
copyButton: {
54+
borderRadius: 7,
55+
background: theme.palette.codeBlock.button.main,
56+
color: theme.palette.codeBlock.button.contrastText,
57+
padding: theme.spacing(0.85),
58+
minWidth: 32,
59+
60+
"&:hover": {
61+
background: theme.palette.codeBlock.button.hover,
62+
},
63+
},
64+
fileCopyIcon: {
65+
width: 20,
66+
height: 20,
67+
},
68+
}))

site/components/Button/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from "./SplitButton"
22
export * from "./LoadingButton"
3+
export * from "./CopyButton"

site/components/CodeBlock/index.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export default {
1212
title: "CodeBlock",
1313
component: CodeBlock,
1414
argTypes: {
15-
lines: { control: "object", defaultValue: sampleLines },
15+
lines: { control: "text", defaultValue: sampleLines },
1616
},
1717
}
1818

site/components/CodeBlock/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { makeStyles } from "@material-ui/core/styles"
22
import React from "react"
3+
import { MONOSPACE_FONT_FAMILY } from "../../theme/constants"
34

45
export interface CodeBlockProps {
56
lines: string[]
@@ -18,8 +19,6 @@ export const CodeBlock: React.FC<CodeBlockProps> = ({ lines }) => {
1819
</div>
1920
)
2021
}
21-
const MONOSPACE_FONT_FAMILY =
22-
"'Fira Code', 'Lucida Console', 'Lucida Sans Typewriter', 'Liberation Mono', 'Monaco', 'Courier New', Courier, monospace"
2322

2423
const useStyles = makeStyles((theme) => ({
2524
root: {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Story } from "@storybook/react"
2+
import React from "react"
3+
import { CodeExample, CodeExampleProps } from "./CodeExample"
4+
5+
const sampleCode = `echo "Hello, world"`
6+
7+
export default {
8+
title: "CodeExample",
9+
component: CodeExample,
10+
argTypes: {
11+
code: { control: "string", defaultValue: sampleCode },
12+
},
13+
}
14+
15+
const Template: Story<CodeExampleProps> = (args: CodeExampleProps) => <CodeExample {...args} />
16+
17+
export const Example = Template.bind({})
18+
Example.args = {
19+
code: sampleCode,
20+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { screen } from "@testing-library/react"
2+
import { render } from "../../test_helpers"
3+
import React from "react"
4+
import { CodeExample } from "./CodeExample"
5+
6+
describe("CodeExample", () => {
7+
it("renders code", async () => {
8+
// When
9+
render(<CodeExample code="echo hello" />)
10+
11+
// Then
12+
// Both lines should be rendered
13+
await screen.findByText("echo hello")
14+
})
15+
})
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { makeStyles } from "@material-ui/core/styles"
2+
import React from "react"
3+
import { MONOSPACE_FONT_FAMILY } from "../../theme/constants"
4+
5+
import { CopyButton } from "../Button"
6+
7+
export interface CodeExampleProps {
8+
code: string
9+
}
10+
11+
/**
12+
* Component to show single-line code examples, with a copy button
13+
*/
14+
export const CodeExample: React.FC<CodeExampleProps> = ({ code }) => {
15+
const styles = useStyles()
16+
17+
return (
18+
<div className={styles.root}>
19+
<code>{code}</code>
20+
<CopyButton text={code} />
21+
</div>
22+
)
23+
}
24+
25+
const useStyles = makeStyles((theme) => ({
26+
root: {
27+
display: "flex",
28+
flexDirection: "row",
29+
justifyContent: "space-between",
30+
alignItems: "center",
31+
background: theme.palette.background.default,
32+
color: theme.palette.codeBlock.contrastText,
33+
fontFamily: MONOSPACE_FONT_FAMILY,
34+
fontSize: 13,
35+
padding: theme.spacing(2),
36+
borderRadius: theme.shape.borderRadius,
37+
},
38+
}))

site/components/CodeExample/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./CodeExample"

site/components/Icons/FileCopy.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import SvgIcon from "@material-ui/core/SvgIcon"
2+
import React from "react"
3+
4+
export const FileCopy: typeof SvgIcon = (props) => (
5+
<SvgIcon {...props} viewBox="0 0 20 20">
6+
<path
7+
d="M12.7412 2.2807H4.32014C3.5447 2.2807 2.91663 2.90877 2.91663 3.68421V13.5088H4.32014V3.68421H12.7412V2.2807ZM14.8465 5.08772H7.12716C6.35172 5.08772 5.72365 5.71579 5.72365 6.49123V16.3158C5.72365 17.0912 6.35172 17.7193 7.12716 17.7193H14.8465C15.6219 17.7193 16.25 17.0912 16.25 16.3158V6.49123C16.25 5.71579 15.6219 5.08772 14.8465 5.08772ZM14.8465 16.3158H7.12716V6.49123H14.8465V16.3158Z"
8+
fill="currentColor"
9+
/>
10+
</SvgIcon>
11+
)

0 commit comments

Comments
 (0)