Skip to content

Commit

Permalink
wip: redesign tabulator tables list, handle errors
Browse files Browse the repository at this point in the history
  • Loading branch information
fiskus committed Oct 1, 2024
1 parent f49474a commit 3fcb400
Showing 1 changed file with 133 additions and 69 deletions.
202 changes: 133 additions & 69 deletions catalog/app/containers/Admin/Buckets/Tabulator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ import RENAME_TABULATOR_TABLE_MUTATION from './gql/TabulatorTablesRename.generat

const TextEditor = React.lazy(() => import('components/FileEditor/TextEditor'))

const isEmpty = (obj: Record<string, any>) => {
const values = Object.values(obj)
if (values.length === 0) return true
return values.every((x) => !x)
}

const TEXT_EDITOR_TYPE = { brace: 'yaml' as const }

type FormValuesSetTable = Pick<Model.GQLTypes.TabulatorTable, 'name' | 'config'>
Expand Down Expand Up @@ -428,14 +434,21 @@ const useAddTableStyles = M.makeStyles((t) => ({
display: 'flex',
flexDirection: 'column',
width: '100%',
alignItems: 'flex-end',
},
button: {
marginLeft: t.spacing(2),
marginLeft: 'auto',
'& + &': {
marginLeft: t.spacing(2),
},
},
editor: {
marginBottom: t.spacing(1),
},
formBottom: {
alignItems: 'center',
display: 'flex',
justifyContent: 'space-between',
},
}))

interface AddTableProps {
Expand All @@ -448,7 +461,7 @@ function AddTable({ disabled, onCancel, onSubmit }: AddTableProps) {
const classes = useAddTableStyles()
return (
<RF.Form onSubmit={onSubmit}>
{({ handleSubmit }) => (
{({ handleSubmit, error, submitError, submitFailed }) => (
<form onSubmit={handleSubmit} className={classes.root}>
<RF.Field
component={Form.Field}
Expand Down Expand Up @@ -479,7 +492,14 @@ function AddTable({ disabled, onCancel, onSubmit }: AddTableProps) {
)}
disabled={disabled}
/>
<div>
<div className={classes.formBottom}>
{submitFailed && (
<Form.FormError
error={error || submitError}
errors={{ unexpected: 'Something went wrong' }}
margin="none"
/>
)}
<M.Button
className={classes.button}
color="primary"
Expand Down Expand Up @@ -510,10 +530,13 @@ function AddTable({ disabled, onCancel, onSubmit }: AddTableProps) {
const useTabulatorRowStyles = M.makeStyles((t) => ({
root: {},
name: {
marginTop: '3px',
marginRight: t.spacing(2),
},
button: {
marginLeft: t.spacing(2),
marginLeft: 'auto',
'& + &': {
marginLeft: t.spacing(2),
},
},
actions: {
display: 'flex',
Expand All @@ -525,10 +548,10 @@ const useTabulatorRowStyles = M.makeStyles((t) => ({
color: t.palette.error.main,
},
config: {
alignItems: 'flex-end',
display: 'flex',
flexDirection: 'column',
width: '100%',
flexGrow: 1,
paddingBottom: t.spacing(2),
},
nameForm: {
display: 'flex',
Expand All @@ -538,6 +561,11 @@ const useTabulatorRowStyles = M.makeStyles((t) => ({
submit: {
marginTop: t.spacing(1),
},
formBottom: {
alignItems: 'center',
display: 'flex',
justifyContent: 'space-between',
},
}))

interface TabulatorRowProps {
Expand All @@ -561,26 +589,20 @@ function TabulatorRow({

const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null)
const [deleteError, setDeleteError] = React.useState<Record<string, string>>({})
// TODO: add FormError component
const handleDelete = React.useCallback(async () => {
const error = await onDelete(tabulatorTable)
setDeleteError(error || {})
}, [onDelete, tabulatorTable])

return (
<>
<M.ListItem
disableGutters
button
onClick={() => setOpen((x) => !x)}
disabled={disabled}
>
<M.ListItem button onClick={() => setOpen((x) => !x)} disabled={disabled}>
<M.ListItemIcon>
<M.Icon>{open ? 'keyboard_arrow_up' : 'keyboard_arrow_down'}</M.Icon>
</M.ListItemIcon>
{editName ? (
{editName && isEmpty(deleteError) ? (
<RF.Form initialValues={tabulatorTable} onSubmit={onRename}>
{({ handleSubmit }) => (
{({ handleSubmit, error, submitError, errors, submitErrors }) => (
<form onSubmit={handleSubmit} className={classes.nameForm}>
<RF.Field
component={Form.Field}
Expand All @@ -593,6 +615,16 @@ function TabulatorRow({
errors={{
required: 'Enter a table name',
}}
helperText={
<Form.FormError
/* @ts-expect-error */
component="span"
errors={{}}
error={error || submitError || errors?.name || submitErrors?.name}
margin="none"
/>
}
disabled={disabled}
/>
<M.Button
className={classes.button}
Expand All @@ -603,6 +635,7 @@ function TabulatorRow({
}}
variant="contained"
color="primary"
disabled={disabled}
>
Rename
</M.Button>
Expand All @@ -614,6 +647,7 @@ function TabulatorRow({
setEditName(false)
}}
color="primary"
disabled={disabled}
>
Cancel
</M.Button>
Expand All @@ -622,10 +656,25 @@ function TabulatorRow({
)}
</RF.Form>
) : (
<M.ListItemText primary={tabulatorTable.name} secondary={deleteError.name} />
<M.ListItemText
primary={tabulatorTable.name}
secondary={
<Form.FormError
/* @ts-expect-error */
component="span"
errors={{}}
error={deleteError.name || deleteError[FF.FORM_ERROR]}
margin="none"
/>
}
/>
)}
<M.ListItemSecondaryAction>
<M.IconButton onClick={(e) => setAnchorEl(e.currentTarget)} size="small">
<M.IconButton
onClick={(e) => setAnchorEl(e.currentTarget)}
size="small"
disabled={disabled}
>
<M.Icon>more_vert</M.Icon>
</M.IconButton>
<M.Menu anchorEl={anchorEl} open={!!anchorEl} onClose={() => setAnchorEl(null)}>
Expand All @@ -634,6 +683,7 @@ function TabulatorRow({
setAnchorEl(null)
setEditName(true)
}}
disabled={disabled}
>
Rename
</M.MenuItem>
Expand All @@ -642,19 +692,27 @@ function TabulatorRow({
setAnchorEl(null)
handleDelete()
}}
disabled={disabled}
>
Delete
</M.MenuItem>
</M.Menu>
</M.ListItemSecondaryAction>
</M.ListItem>
<M.Collapse in={open || !!deleteError.config}>
<M.ListItem disableGutters disabled={editName}>
<M.ListItem disabled={editName}>
<RF.Form
initialValues={tabulatorTable}
onSubmit={(values) => onSubmit({ ...tabulatorTable, ...values })}
>
{({ handleSubmit }) => (
{({
handleSubmit,
error,
errors,
submitErrors,
submitError,
submitFailed,
}) => (
<form onSubmit={handleSubmit} className={classes.config}>
<RF.Field
className={classes.editor}
Expand All @@ -667,25 +725,35 @@ function TabulatorRow({
validate={validators.composeAnd(
validators.required as FF.FieldValidator<any>,
validateYaml,
// validateTable,
validateTable,
)}
disabled={disabled}
/>
<M.Button
className={classes.button}
color="primary"
disabled={disabled}
onClick={handleSubmit}
size="small"
type="submit"
variant="contained"
>
Save
</M.Button>
<div className={classes.formBottom}>
{submitFailed && (
<Form.FormError
errors={{}}
error={error || submitError || errors?.name || submitErrors?.name}
margin="none"
/>
)}
<M.Button
className={classes.button}
color="primary"
disabled={disabled}
onClick={handleSubmit}
size="small"
type="submit"
variant="contained"
>
Save
</M.Button>
</div>
</form>
)}
</RF.Form>
</M.ListItem>
<M.Divider />
</M.Collapse>
</>
)
Expand All @@ -709,32 +777,11 @@ function parseResponseError(
}

const useStyles = M.makeStyles((t) => ({
actions: {
margin: t.spacing(2, 0, 0),
display: 'flex',
justifyContent: 'flex-end',
},
button: {
marginLeft: 'auto',
},
empty: {
paddingBottom: t.spacing(2),
},
item: {
position: 'relative',
'& + &': {
marginTop: t.spacing(3),
paddingTop: t.spacing(3),
'&::before': {
background: t.palette.divider,
content: '""',
height: '1px',
left: t.spacing(2),
position: 'absolute',
right: t.spacing(2),
top: 0,
},
},
textPlaceholder: {
height: t.spacing(3),
},
}))

Expand Down Expand Up @@ -843,41 +890,58 @@ export default function Tabulator({
[bucketName, notify, setTabulatorTable],
)

const onSubmitNew = React.useCallback(
async (values: FormValuesSetTable): Promise<FF.SubmissionErrors | undefined> => {
const error = await onSubmit(values)
if (!error) {
setToAdd(false)
}
return error
},
[onSubmit],
)

const classes = useStyles()

if (!tabulatorTables.length && !toAdd) {
return <Empty className={classes.empty} onClick={() => setToAdd(true)} />
}
return (
<>
<M.List disablePadding>
<M.List>
{tabulatorTables.map((tabulatorTable) => (
<TabulatorRow
disabled={submitting}
key={tabulatorTable.name}
disabled={submitting}
onDelete={onDelete}
onRename={onRename}
onSubmit={onSubmit}
tabulatorTable={tabulatorTable}
/>
))}
<M.ListItem disableGutters>
</M.List>
<M.Divider />
<M.List>
<M.ListItem>
{toAdd ? (
<AddTable
disabled={submitting}
onCancel={() => setToAdd(false)}
onSubmit={onSubmit}
onSubmit={onSubmitNew}
/>
) : (
<M.Button
className={classes.button}
disabled={toAdd}
size="small"
onClick={() => setToAdd(true)}
type="button"
>
Add table
</M.Button>
<>
<M.ListItemText primary={<div className={classes.textPlaceholder}></div>} />
<M.ListItemSecondaryAction>
<M.Button
disabled={submitting}
onClick={() => setToAdd(true)}
type="button"
>
Add table
</M.Button>
</M.ListItemSecondaryAction>
</>
)}
</M.ListItem>
</M.List>
Expand Down

0 comments on commit 3fcb400

Please sign in to comment.