Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CrossBucket push, frontend #1932

Merged
merged 107 commits into from
Dec 3, 2020
Merged
Show file tree
Hide file tree
Changes from 105 commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
f6886e6
add CopyButton
fiskus Nov 20, 2020
30a3dd4
add data wrapper
fiskus Nov 20, 2020
ffca744
show Skeleton
fiskus Nov 20, 2020
c0cf59c
Merge branch 'master' of github.com:quiltdata/quilt into crossbucket-…
fiskus Nov 23, 2020
625f53a
add CopyButton
fiskus Nov 20, 2020
f9b39e5
add data wrapper
fiskus Nov 20, 2020
c88927d
show Skeleton
fiskus Nov 20, 2020
302c057
wip
fiskus Nov 23, 2020
b1f7db0
WIP
fiskus Nov 23, 2020
2ed6133
mock buckets list
fiskus Nov 23, 2020
d586296
wip
fiskus Nov 23, 2020
e6f9cef
add FileEntry
fiskus Nov 24, 2020
6484d71
add DropMessage
fiskus Nov 24, 2020
1482bdd
add DropzoneOverlay
fiskus Nov 24, 2020
9bb8441
add Dropzone.Header
fiskus Nov 24, 2020
ad95f2d
use regular component syntax
fiskus Nov 24, 2020
3a846b8
use wildcard import
fiskus Nov 24, 2020
e353c31
add Dropzone.Area component
fiskus Nov 24, 2020
84c1800
move files container to Dropzone.Area
fiskus Nov 24, 2020
eca9c8d
use default for import
fiskus Nov 24, 2020
4ca1fc0
use successors from workflows config
fiskus Nov 24, 2020
6301b03
change title and icon
fiskus Nov 25, 2020
de67692
place menu at the bottom
fiskus Nov 25, 2020
9a4953b
polish dialogs
fiskus Nov 25, 2020
cbacf4c
ordinary ticks are enough
fiskus Nov 25, 2020
0af1e8a
use DialogLoading from PD
fiskus Nov 25, 2020
8b69615
use DialogLoading for PackageCreateDialog too
fiskus Nov 25, 2020
635f0be
DialogError standalone component
fiskus Nov 25, 2020
485d093
use DialogSucces component
fiskus Nov 25, 2020
4c3826c
successors -> destination-registries
fiskus Nov 26, 2020
87c48fb
merge with experimental branch
fiskus Nov 26, 2020
2835e22
remove icon
fiskus Nov 26, 2020
b0274fe
use DialogSuccess module
fiskus Nov 26, 2020
dba5935
Merge branch 'master' of github.com:quiltdata/quilt into crossbucket-…
fiskus Nov 26, 2020
e6eaab2
push new package without files
fiskus Nov 26, 2020
bfe8384
rename Area to Dropzone
fiskus Nov 27, 2020
c606eb0
should return the same files list
fiskus Nov 27, 2020
9c9852e
styles are order dependent
fiskus Nov 27, 2020
19c20b9
cache with useMemo
fiskus Nov 27, 2020
4f2934f
polish warning data
fiskus Nov 27, 2020
18f0165
FilesStats component
fiskus Nov 27, 2020
5381465
move select to component
fiskus Nov 27, 2020
8ae6aa9
merge with master
fiskus Nov 27, 2020
cea8a4a
fix files format
fiskus Nov 27, 2020
7718fe2
remove extra export
fiskus Nov 27, 2020
c600f70
add react snapshot tests
fiskus Nov 27, 2020
e305e23
merge with master
fiskus Nov 30, 2020
6ce1cc9
Merge branch 'master' of github.com:quiltdata/quilt into crossbucket-…
fiskus Nov 30, 2020
74e500b
more natural MUI menu
fiskus Nov 30, 2020
cd2dfb8
icon for button, rearrange buttons
fiskus Nov 30, 2020
e28b40e
fix transition from revision to hash
fiskus Nov 30, 2020
1a0250f
remove Icon for attachment
fiskus Nov 30, 2020
2d419a3
show bucket url
fiskus Nov 30, 2020
c9c8282
add error and empty states
fiskus Nov 30, 2020
6808431
tie up API
fiskus Nov 30, 2020
9955fc1
fix top_hash property
fiskus Nov 30, 2020
9e0afbb
remove dead code
fiskus Nov 30, 2020
e787eae
promote → push
fiskus Nov 30, 2020
9d8cf5e
cosmetic changes
fiskus Nov 30, 2020
c571c1b
remove dead code
fiskus Nov 30, 2020
521953a
reset revision hash onSuccess/onClose
fiskus Dec 1, 2020
29b559a
use component pathnames within test names
fiskus Dec 1, 2020
2fe11c3
copy data swticher
fiskus Dec 1, 2020
68191cc
revert PackageCreateDialog changes: adding loading and error states
fiskus Dec 1, 2020
3367af0
Update catalog/app/containers/Bucket/CopyButton.js
fiskus Dec 1, 2020
7aa43af
Object.keys → object.entries
fiskus Dec 1, 2020
b1def53
add simple test for successors
fiskus Dec 1, 2020
7db5ba1
mobile ready for CopyButton
fiskus Dec 1, 2020
85f6a3b
remove unnecessary Fragment
fiskus Dec 1, 2020
0bd40ef
dont copy files by default
fiskus Dec 1, 2020
0954250
Merge branch 'master' of github.com:quiltdata/quilt into crossbucket-…
fiskus Dec 1, 2020
14b033f
cosmetic change
fiskus Dec 1, 2020
e91318a
Merge branch 'crossbucket-push-frontend' of github.com:quiltdata/quil…
fiskus Dec 1, 2020
441917a
rename Component → Element
fiskus Dec 1, 2020
48e46a5
update tests names
fiskus Dec 1, 2020
9ca8b49
remove ref
fiskus Dec 1, 2020
803956e
refactor AsyncResult thing
fiskus Dec 1, 2020
159d985
remove files
fiskus Dec 1, 2020
aaf8e58
handle the error
fiskus Dec 1, 2020
dae8f9a
Copying files notification
fiskus Dec 1, 2020
aa4b8cc
fragment when possible
fiskus Dec 1, 2020
d0b9dee
adjust height for Skeleton
fiskus Dec 1, 2020
875439c
useData inline in component
fiskus Dec 1, 2020
0625bc9
update text for successfull message
fiskus Dec 1, 2020
20dfd37
add hint icon for CopyDataSwitcher
fiskus Dec 1, 2020
3048160
remove doulbe for aria-haspopup
fiskus Dec 1, 2020
53e9629
fix ref issue
fiskus Dec 1, 2020
f735038
use Checkbox
fiskus Dec 1, 2020
a8bdf63
Update catalog/app/containers/Bucket/PackageCopyDialog.js
fiskus Dec 1, 2020
8945de4
Update catalog/app/containers/Bucket/PackageCopyDialog.js
fiskus Dec 1, 2020
89e0494
use copy_data for workflows config
fiskus Dec 1, 2020
50ce51f
base copyData on config data
fiskus Dec 1, 2020
1108317
Merge branch 'crossbucket-push-frontend' of github.com:quiltdata/quil…
fiskus Dec 1, 2020
ce2b2ec
Merge branch 'master' of github.com:quiltdata/quilt into crossbucket-…
fiskus Dec 1, 2020
dbeecc7
narrower viewport edges
fiskus Dec 2, 2020
23b738f
square icon
fiskus Dec 2, 2020
dee7a9a
use copy_data from successor
fiskus Dec 2, 2020
4de9ef7
remove copyData param
fiskus Dec 2, 2020
928503e
copyData is true by default
fiskus Dec 2, 2020
2fb9f57
remove push-to-bucket icon
fiskus Dec 2, 2020
dce9efc
Update catalog/app/utils/workflows.spec.js
fiskus Dec 2, 2020
612d82d
fix default copy_data value
fiskus Dec 2, 2020
eb70237
Merge branch 'master' of github.com:quiltdata/quilt into crossbucket-…
fiskus Dec 2, 2020
3448278
different Skeleton for Copy and Update dialogs
fiskus Dec 2, 2020
4d268bd
remove extra try/catch
fiskus Dec 2, 2020
ed3f22f
fix closing DialogError
fiskus Dec 2, 2020
dbd68c3
Merge branch 'master' of github.com:quiltdata/quilt into crossbucket-…
fiskus Dec 2, 2020
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
45 changes: 45 additions & 0 deletions catalog/app/components/Dropzone/DropMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import cx from 'classnames'
import * as React from 'react'
import * as M from '@material-ui/core'

const useStyles = M.makeStyles((t) => ({
root: {
...t.typography.body2,
alignItems: 'center',
display: 'flex',
flexGrow: 1,
justifyContent: 'center',
minHeight: t.spacing(4),
paddingBottom: t.spacing(1),
paddingTop: t.spacing(1),
textAlign: 'center',
},
warning: {
color: t.palette.warning.dark,
},
error: {
color: t.palette.error.main,
},
}))

export default function DropMessage({ disabled, error, warning }) {
const classes = useStyles()

const label = React.useMemo(() => {
if (error) return error
if (warning) return warning
if (disabled) return ''
return 'Drop files here or click to browse'
}, [disabled, error, warning])

return (
<div
className={cx(classes.root, {
[classes.error]: !!error,
[classes.warning]: !!warning,
})}
>
{label}
</div>
)
}
30 changes: 30 additions & 0 deletions catalog/app/components/Dropzone/DropMessage.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as React from 'react'
import renderer from 'react-test-renderer'

import DropMessage from './DropMessage'

describe('components/Dropzone/DropMessage', () => {
it('should render with default message', () => {
const tree = renderer.create(<DropMessage />).toJSON()
expect(tree).toMatchSnapshot()
})

it('should render error', () => {
const tree = renderer
.create(<DropMessage error="This is errror" warning="This is warning" />)
.toJSON()
expect(tree).toMatchSnapshot()
})

it('should render warning', () => {
const tree = renderer.create(<DropMessage warning="This is warning" />).toJSON()
expect(tree).toMatchSnapshot()
})

it('should be empty when disabled', () => {
const tree = renderer
.create(<DropMessage disabled error="This is errror" warning="This is warning" />)
.toJSON()
expect(tree).toMatchSnapshot()
})
})
100 changes: 100 additions & 0 deletions catalog/app/components/Dropzone/Dropzone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import cx from 'classnames'
import * as React from 'react'
import { useDropzone } from 'react-dropzone'
import * as M from '@material-ui/core'

import DropMessage from './DropMessage'
import FileEntry from './FileEntry'
import Header from './Header'

const useStyles = M.makeStyles((t) => ({
dropzone: {
marginTop: t.spacing(2),
nl0 marked this conversation as resolved.
Show resolved Hide resolved
position: 'relative',
},
dropArea: {
background: t.palette.action.hover,
border: `1px solid ${t.palette.action.disabled}`,
borderRadius: t.shape.borderRadius,
cursor: 'pointer',
display: 'flex',
flexDirection: 'column',
minHeight: 140,
outline: 'none',
overflow: 'hidden',
},
dragOver: {
background: t.palette.action.selected,
},
warning: {
borderColor: t.palette.warning.dark,
},
error: {
borderColor: t.palette.error.main,
},
files: {
borderBottom: `1px solid ${t.palette.action.disabled}`,
maxHeight: 200,
overflowX: 'hidden',
overflowY: 'auto',
},
}))

export default function Dropzone({
className,
disabled,
error,
files,
onDrop,
overlayElement,
statsElement,
warning,
}) {
const classes = useStyles()

const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop })

return (
<div className={className}>
<Header disabled error={error} warning={warning}>
{statsElement}
</Header>

<div className={classes.dropzone}>
<div
{...getRootProps({
className: cx(classes.dropArea, {
[classes.dragOver]: isDragActive && !disabled,
[classes.error]: !!error,
[classes.warning]: !!warning,
}),
})}
>
<input {...getInputProps()} />

{!!files.length && (
<div
className={cx(classes.files, {
[classes.error]: !!error,
[classes.warning]: !!warning,
})}
>
{files.map((file) => (
<FileEntry
iconName={file.iconName}
key={file.key}
path={file.path}
size={file.size}
/>
))}
</div>
)}

<DropMessage disabled={disabled} error={error} warning={warning} />
</div>

{overlayElement}
</div>
</div>
)
}
11 changes: 11 additions & 0 deletions catalog/app/components/Dropzone/Dropzone.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react'
import renderer from 'react-test-renderer'

import Dropzone from './Dropzone'

describe('components/Dropzone/Dropzone', () => {
it('should render', () => {
const tree = renderer.create(<Dropzone files={[]} />).toJSON()
expect(tree).toMatchSnapshot()
})
})
52 changes: 52 additions & 0 deletions catalog/app/components/Dropzone/FileEntry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import cx from 'classnames'
import * as React from 'react'
import * as M from '@material-ui/core'

import { readableBytes } from 'utils/string'

const useStyles = M.makeStyles((t) => ({
root: {
alignItems: 'center',
background: t.palette.background.paper,
display: 'flex',
'&:not(:last-child)': {
borderBottomStyle: 'solid',
borderBottomWidth: '1px',
borderColor: 'inherit',
},
},
noIcon: {
paddingLeft: t.spacing(1),
},
filePath: {
...t.typography.body2,
flexGrow: 1,
marginRight: t.spacing(1),
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
},
fileSize: {
...t.typography.body2,
color: t.palette.text.secondary,
marginRight: t.spacing(0.5),
},
}))

export default function FileEntry({ className, iconName, path, size, title, onClick }) {
const classes = useStyles()

return (
<div className={cx(classes.root, className, { [classes.noIcon]: !iconName })}>
{iconName && (
<M.IconButton onClick={onClick} size="small" title={title}>
<M.Icon fontSize="inherit">{iconName}</M.Icon>
</M.IconButton>
)}
<div className={classes.filePath} title={path}>
{path}
</div>
<div className={classes.fileSize}>{readableBytes(size)}</div>
</div>
)
}
27 changes: 27 additions & 0 deletions catalog/app/components/Dropzone/FilesStats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as React from 'react'
import * as M from '@material-ui/core'

import { readableBytes } from 'utils/string'

const useStyles = M.makeStyles(() => ({
icon: {
marginLeft: 4,
},
}))

export default function FilesStats({ files, warning }) {
const classes = useStyles()

const totalSize = React.useMemo(() => files.reduce((sum, f) => sum + f.size, 0), [
files,
])

if (!files.length) return null

return (
<span>
: {files.length} ({readableBytes(totalSize)})
{warning && <M.Icon className={classes.icon}>error_outline</M.Icon>}
</span>
)
}
19 changes: 19 additions & 0 deletions catalog/app/components/Dropzone/FilesStats.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react'
import renderer from 'react-test-renderer'

import FilesStats from './FilesStats'

describe('components/Dropzone/FilesStats', () => {
it('should render', () => {
const tree = renderer.create(<FilesStats files={[]} />).toJSON()
expect(tree).toMatchSnapshot()
})

// FIXME: fix "jest + react-intl"
it.skip('should render files total size', () => {
const tree = renderer
.create(<FilesStats files={[{ size: 100000 }, { size: 200000 }]} />)
.toJSON()
expect(tree).toMatchInlineSnapshot()
})
})
43 changes: 43 additions & 0 deletions catalog/app/components/Dropzone/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import cx from 'classnames'
import * as React from 'react'
import * as M from '@material-ui/core'

const useStyles = M.makeStyles((t) => ({
root: {
alignItems: 'center',
display: 'flex',
height: 24,
},
title: {
...t.typography.body1,
display: 'flex',
},
warning: {
color: t.palette.warning.dark,
},
error: {
color: t.palette.error.main,
},
disabled: {
color: t.palette.text.secondary,
},
}))

export default function Header({ children, disabled, error, warning }) {
const classes = useStyles()

return (
<div className={classes.root}>
<div
className={cx(classes.title, {
[classes.disabled]: disabled,
[classes.error]: !!error,
[classes.warning]: !!warning,
})}
>
Files
{children}
fiskus marked this conversation as resolved.
Show resolved Hide resolved
</div>
</div>
)
}
21 changes: 21 additions & 0 deletions catalog/app/components/Dropzone/Header.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from 'react'
import renderer from 'react-test-renderer'

import Header from './Header'

describe('components/Dropzone/Header', () => {
it('should render', () => {
const tree = renderer.create(<Header />).toJSON()
expect(tree).toMatchSnapshot()
})

it('should change color on error', () => {
const tree = renderer.create(<Header error />).toJSON()
expect(tree).toMatchSnapshot()
})

it('should change color on warning', () => {
const tree = renderer.create(<Header warning />).toJSON()
expect(tree).toMatchSnapshot()
})
})
26 changes: 26 additions & 0 deletions catalog/app/components/Dropzone/Overlay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import cx from 'classnames'
import * as React from 'react'
import * as M from '@material-ui/core'

const useStyles = M.makeStyles((t) => ({
root: {
alignItems: 'center',
background: t.palette.action.disabledBackground,
border: `1px solid ${t.palette.action.disabled}`,
borderRadius: t.shape.borderRadius,
bottom: 0,
cursor: 'not-allowed',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
left: 0,
position: 'absolute',
right: 0,
top: 0,
},
}))

export default function Overlay({ children, className }) {
const classes = useStyles()
return <div className={cx(classes.root, className)}>{children}</div>
}
Loading