|
|
|
@ -5,24 +5,28 @@ import Button from './Button'
|
|
|
|
|
import Toolbar from './Toolbar'
|
|
|
|
|
import Input from './Input'
|
|
|
|
|
import ConfirmButton from './ConfirmButton'
|
|
|
|
|
import Popout, { managePopout } from './Popout'
|
|
|
|
|
import { Down as ArrowDown } from './svg/Arrows'
|
|
|
|
|
import { useAPI } from './ApiContext'
|
|
|
|
|
import { useAuth } from './AuthContext'
|
|
|
|
|
|
|
|
|
|
import { COLORS } from '../lib/constants'
|
|
|
|
|
|
|
|
|
|
const popoutStyle = { width: '144px', right: 15, top: 40 }
|
|
|
|
|
|
|
|
|
|
function DeleteButton(props) {
|
|
|
|
|
const [onClick, { loading }] = useAsyncCallback(props.onClick)
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<ConfirmButton
|
|
|
|
|
display="block"
|
|
|
|
|
padding="0 16px"
|
|
|
|
|
padding="8px"
|
|
|
|
|
flex="unset"
|
|
|
|
|
center
|
|
|
|
|
border
|
|
|
|
|
large
|
|
|
|
|
color="#fff"
|
|
|
|
|
onClick={onClick}
|
|
|
|
|
style={{ color: COLORS.RED }}
|
|
|
|
|
style={{ color: COLORS.RED, borderTop: `1px solid ${COLORS.GREEN}` }}
|
|
|
|
|
>
|
|
|
|
|
{loading ? 'Deleting…' : 'Delete'}
|
|
|
|
|
</ConfirmButton>
|
|
|
|
@ -35,13 +39,11 @@ function DuplicateButton(props) {
|
|
|
|
|
return (
|
|
|
|
|
<Button
|
|
|
|
|
display="block"
|
|
|
|
|
padding="0 16px"
|
|
|
|
|
margin="0 0 0 1rem"
|
|
|
|
|
padding="8px"
|
|
|
|
|
flex="unset"
|
|
|
|
|
center
|
|
|
|
|
border
|
|
|
|
|
large
|
|
|
|
|
color="#37b589"
|
|
|
|
|
color={COLORS.GREEN}
|
|
|
|
|
onClick={onClick}
|
|
|
|
|
>
|
|
|
|
|
{loading ? 'Duplicating…' : 'Duplicate'}
|
|
|
|
@ -49,15 +51,50 @@ function DuplicateButton(props) {
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function SnippetToolbar(props) {
|
|
|
|
|
function SnippetToolbar({
|
|
|
|
|
toggleVisibility,
|
|
|
|
|
isVisible,
|
|
|
|
|
snippet,
|
|
|
|
|
setSnippet,
|
|
|
|
|
setToasts,
|
|
|
|
|
state,
|
|
|
|
|
...props
|
|
|
|
|
}) {
|
|
|
|
|
const user = useAuth()
|
|
|
|
|
const online = useOnline()
|
|
|
|
|
const api = useAPI()
|
|
|
|
|
const [update, { loading }] = useAsyncCallback(api.snippet.update)
|
|
|
|
|
|
|
|
|
|
if (!online) return null
|
|
|
|
|
if (!user) return null
|
|
|
|
|
if (!props.snippet) return null
|
|
|
|
|
|
|
|
|
|
const sameUser = user.uid === props.snippet.userId
|
|
|
|
|
const sameUser = snippet && user.uid === snippet.userId
|
|
|
|
|
|
|
|
|
|
// TODO move this to Editor
|
|
|
|
|
function saveSnippet() {
|
|
|
|
|
if (loading || !user) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!snippet) {
|
|
|
|
|
update(undefined, state).then(newSnippet => {
|
|
|
|
|
if (newSnippet && newSnippet.id) {
|
|
|
|
|
setSnippet(newSnippet)
|
|
|
|
|
setToasts({
|
|
|
|
|
type: 'ADD',
|
|
|
|
|
toast: { children: 'Snippet saved!', closable: true },
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
} else if (sameUser) {
|
|
|
|
|
update(snippet.id, state).then(() => {
|
|
|
|
|
setToasts({
|
|
|
|
|
type: 'ADD',
|
|
|
|
|
toast: { children: 'Snippet saved!', closable: true },
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Toolbar
|
|
|
|
@ -66,12 +103,44 @@ function SnippetToolbar(props) {
|
|
|
|
|
marginBottom: 0,
|
|
|
|
|
flexDirection: 'row-reverse',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
// justifyContent: 'space-between',
|
|
|
|
|
zIndex: 1,
|
|
|
|
|
position: 'relative',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<DuplicateButton onClick={props.onCreate} />
|
|
|
|
|
{sameUser && <DeleteButton onClick={props.onDelete} />}
|
|
|
|
|
<div className="flex">
|
|
|
|
|
<Button
|
|
|
|
|
border
|
|
|
|
|
large
|
|
|
|
|
center
|
|
|
|
|
color={COLORS.GREEN}
|
|
|
|
|
onClick={saveSnippet}
|
|
|
|
|
data-cy="save-button"
|
|
|
|
|
style={{ minWidth: 84, borderBottomRightRadius: 0, borderTopRightRadius: 0 }}
|
|
|
|
|
title="Save"
|
|
|
|
|
disabled={loading}
|
|
|
|
|
>
|
|
|
|
|
{loading ? 'Saving…' : 'Save'}
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
id="save-menu"
|
|
|
|
|
title="Save menu dropdown"
|
|
|
|
|
border
|
|
|
|
|
large
|
|
|
|
|
center
|
|
|
|
|
color={COLORS.GREEN}
|
|
|
|
|
padding="0 8px"
|
|
|
|
|
margin="0 8px 0 -1px"
|
|
|
|
|
onClick={toggleVisibility}
|
|
|
|
|
data-cy="save-button"
|
|
|
|
|
style={{
|
|
|
|
|
borderBottomLeftRadius: 0,
|
|
|
|
|
borderTopLeftRadius: 0,
|
|
|
|
|
maxWidth: '26px',
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<ArrowDown color={COLORS.GREEN} />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{ marginRight: 'auto' }}>
|
|
|
|
|
<Input
|
|
|
|
|
align="left"
|
|
|
|
@ -81,8 +150,21 @@ function SnippetToolbar(props) {
|
|
|
|
|
onChange={e => props.onChange('name', e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<Popout hidden={!isVisible} borderColor={COLORS.GREEN} pointerRight="7px" style={popoutStyle}>
|
|
|
|
|
<div className="menu flex">
|
|
|
|
|
<DuplicateButton onClick={props.onCreate} />
|
|
|
|
|
{sameUser && <DeleteButton onClick={props.onDelete} />}
|
|
|
|
|
</div>
|
|
|
|
|
</Popout>
|
|
|
|
|
<style jsx>
|
|
|
|
|
{`
|
|
|
|
|
.menu {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
|
|
|
|
`}
|
|
|
|
|
</style>
|
|
|
|
|
</Toolbar>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default SnippetToolbar
|
|
|
|
|
export default managePopout(SnippetToolbar)
|
|
|
|
|