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

Package dialog layout: tabs #1999

Closed
wants to merge 6 commits into from
Closed
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
2 changes: 1 addition & 1 deletion catalog/app/components/JsonEditor/JsonEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const useStyles = M.makeStyles((t) => ({
},
inner: {
display: 'flex',
maxHeight: t.spacing(46),
maxHeight: t.spacing(30),
overflow: 'auto',
},
}))
Expand Down
22 changes: 22 additions & 0 deletions catalog/app/containers/Bucket/PackageCopyDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ function DialogTitle({ bucket }) {
)
}

const useStyles = M.makeStyles((t) => ({
tabs: {
marginTop: t.spacing(2),
},
}))

function DialogForm({
close,
hash,
Expand All @@ -98,6 +104,7 @@ function DialogForm({
workflowsConfig,
}) {
const nameValidator = PD.useNameValidator()
const classes = useStyles()

const initialMeta = React.useMemo(
() => ({
Expand Down Expand Up @@ -140,6 +147,7 @@ function DialogForm({
submitting,
submitFailed,
error,
errors,
submitError,
hasValidationErrors,
form,
Expand Down Expand Up @@ -182,6 +190,20 @@ function DialogForm({
margin="normal"
/>

<PD.Tabs
className={classes.tabs}
errors={
submitFailed
? {
[PD.TABS.METADATA.key]: errors.meta,
}
: {}
}
onTabChange={R.identity}
tab={PD.TABS.METADATA}
tabsList={[PD.TABS.METADATA]}
/>

<PD.SchemaFetcher
schemaUrl={R.pathOr('', ['schema', 'url'], values.workflow)}
>
Expand Down
231 changes: 133 additions & 98 deletions catalog/app/containers/Bucket/PackageCreateDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const useFilesInputStyles = M.makeStyles((t) => ({
alignItems: 'center',
display: 'flex',
height: 24,
marginTop: t.spacing(1),
},
headerFiles: {
...t.typography.body1,
Expand Down Expand Up @@ -220,40 +221,6 @@ function FilesInput({
const totalProgress = React.useMemo(() => getTotalProgress(uploads), [uploads])
return (
<div className={classes.root}>
<div className={classes.header}>
<div
className={cx(
classes.headerFiles,
disabled // eslint-disable-line no-nested-ternary
? classes.headerFilesDisabled
: error // eslint-disable-line no-nested-ternary
? classes.headerFilesError
: warn
? classes.headerFilesWarn
: undefined,
)}
>
Files
{!!value.length && (
<>
: {value.length} ({readableBytes(totalSize)})
{warn && <M.Icon style={{ marginLeft: 4 }}>error_outline</M.Icon>}
</>
)}
</div>
<M.Box flexGrow={1} />
{!!value.length && (
<M.Button
onClick={clearFiles}
disabled={disabled}
size="small"
endIcon={<M.Icon fontSize="small">clear</M.Icon>}
>
clear files
</M.Button>
)}
</div>

<div className={classes.dropzoneContainer}>
<div
{...getRootProps({
Expand Down Expand Up @@ -315,6 +282,39 @@ function FilesInput({
</div>
)}
</div>

<div className={classes.header}>
<div
className={cx(
classes.headerFiles,
disabled // eslint-disable-line no-nested-ternary
? classes.headerFilesDisabled
: error // eslint-disable-line no-nested-ternary
? classes.headerFilesError
: warn
? classes.headerFilesWarn
: undefined,
)}
>
{!!value.length && (
<>
Number of files: {value.length} ({readableBytes(totalSize)})
{warn && <M.Icon style={{ marginLeft: 4 }}>error_outline</M.Icon>}
</>
)}
</div>
<M.Box flexGrow={1} />
{!!value.length && (
<M.Button
onClick={clearFiles}
disabled={disabled}
size="small"
endIcon={<M.Icon fontSize="small">clear</M.Icon>}
>
clear files
</M.Button>
)}
</div>
</div>
)
}
Expand All @@ -334,6 +334,12 @@ const getTotalProgress = R.pipe(
}),
)

const useStyles = M.makeStyles((t) => ({
tabs: {
marginTop: t.spacing(2),
},
}))

function PackageCreateDialog({
bucket,
open,
Expand All @@ -349,6 +355,7 @@ function PackageCreateDialog({
const [uploads, setUploads] = React.useState({})
const [success, setSuccess] = React.useState(null)
const nameValidator = PD.useNameValidator()
const classes = useStyles()

const reset = (form) => () => {
form.restart()
Expand Down Expand Up @@ -462,12 +469,15 @@ function PackageCreateDialog({
}
}

const [tab, setTab] = React.useState(PD.TABS.FILES)

return (
<RF.Form onSubmit={uploadPackage}>
{({
handleSubmit,
submitting,
submitFailed,
errors,
error,
submitError,
hasValidationErrors,
Expand Down Expand Up @@ -533,71 +543,96 @@ function PackageCreateDialog({
<M.DialogTitle>Create package</M.DialogTitle>
<M.DialogContent style={{ paddingTop: 0 }}>
<form onSubmit={handleSubmit}>
<RF.Field
component={PD.Field}
name="name"
label="Name"
placeholder="Enter a package name"
validate={validators.composeAsync(
validators.required,
nameValidator.validate,
)}
validateFields={['name']}
errors={{
required: 'Enter a package name',
invalid: 'Invalid package name',
}}
margin="normal"
fullWidth
/>

<RF.Field
component={PD.Field}
name="msg"
label="Commit message"
placeholder="Enter a commit message"
validate={validators.required}
validateFields={['msg']}
errors={{
required: 'Enter a commit message',
}}
fullWidth
margin="normal"
/>
<div>
<RF.Field
component={PD.Field}
name="name"
label="Name"
placeholder="Enter a package name"
validate={validators.composeAsync(
validators.required,
nameValidator.validate,
)}
validateFields={['name']}
errors={{
required: 'Enter a package name',
invalid: 'Invalid package name',
}}
margin="normal"
fullWidth
/>

<RF.Field
component={PD.Field}
name="msg"
label="Commit message"
placeholder="Enter a commit message"
validate={validators.required}
validateFields={['msg']}
errors={{
required: 'Enter a commit message',
}}
fullWidth
margin="normal"
/>
</div>

<RF.Field
component={FilesInput}
name="files"
validate={validators.nonEmpty}
validateFields={['files']}
errors={{
nonEmpty: 'Add files to create a package',
}}
uploads={uploads}
setUploads={setUploads}
isEqual={R.equals}
<PD.Tabs
className={classes.tabs}
errors={
submitFailed
? {
[PD.TABS.FILES.key]: errors.files,
[PD.TABS.METADATA.key]: errors.meta,
}
: {}
}
onTabChange={setTab}
tab={tab}
tabsList={[PD.TABS.FILES, PD.TABS.METADATA]}
/>

<PD.SchemaFetcher
schemaUrl={R.pathOr('', ['schema', 'url'], values.workflow)}
>
{AsyncResult.case({
Ok: ({ responseError, schema, validate }) => (
<RF.Field
component={PD.MetaInput}
name="meta"
bucket={bucket}
schema={schema}
schemaError={responseError}
validate={validate}
validateFields={['meta']}
isEqual={R.equals}
initialValue={PD.EMPTY_META_VALUE}
/>
),
_: () => <PD.MetaInputSkeleton />,
})}
</PD.SchemaFetcher>
<M.Collapse in={tab === PD.TABS.FILES}>
<div>
<RF.Field
component={FilesInput}
name="files"
validate={validators.nonEmpty}
validateFields={['files']}
errors={{
nonEmpty: 'Add files to create a package',
}}
uploads={uploads}
setUploads={setUploads}
isEqual={R.equals}
/>
</div>
</M.Collapse>

<M.Collapse in={tab === PD.TABS.METADATA}>
<div>
<PD.SchemaFetcher
schemaUrl={R.pathOr('', ['schema', 'url'], values.workflow)}
>
{AsyncResult.case({
Ok: ({ responseError, schema, validate }) => (
<RF.Field
component={PD.MetaInput}
name="meta"
bucket={bucket}
schema={schema}
schemaError={responseError}
validate={validate}
validateFields={['meta']}
isEqual={R.equals}
initialValue={PD.EMPTY_META_VALUE}
/>
),
_: () => <PD.MetaInputSkeleton />,
})}
</PD.SchemaFetcher>
</div>
</M.Collapse>

<RF.Field
component={PD.WorkflowInput}
Expand All @@ -618,7 +653,7 @@ function PackageCreateDialog({
{submitting && (
<Delay ms={200} alwaysRender>
{(ready) => (
<M.Fade in={ready}>
<M.Collapse in={ready}>
<M.Box flexGrow={1} display="flex" alignItems="center" pl={2}>
<M.CircularProgress
size={24}
Expand All @@ -640,7 +675,7 @@ function PackageCreateDialog({
: 'Writing manifest'}
</M.Typography>
</M.Box>
</M.Fade>
</M.Collapse>
)}
</Delay>
)}
Expand Down
Loading