kafka-ui/kafka-ui-react-app/src/components/Topics/New/New.tsx
2020-03-01 16:07:33 +02:00

253 lines
8.5 KiB
TypeScript

import React from 'react';
import { ClusterName, CleanupPolicy, TopicFormData, TopicName } from 'redux/interfaces';
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
import { clusterTopicsPath } from 'lib/paths';
import { useForm, ErrorMessage } from 'react-hook-form';
import {
TOPIC_NAME_VALIDATION_PATTERN,
MILLISECONDS_IN_DAY,
BYTES_IN_GB,
} from 'lib/constants';
interface Props {
clusterName: ClusterName;
isTopicCreated: boolean;
createTopic: (clusterName: ClusterName, form: TopicFormData) => void;
redirectToTopicPath: (clusterName: ClusterName, topicName: TopicName) => void;
resetUploadedState: () => void;
}
const New: React.FC<Props> = ({
clusterName,
isTopicCreated,
createTopic,
redirectToTopicPath,
resetUploadedState
}) => {
const {register, handleSubmit, errors, getValues} = useForm<TopicFormData>();
const [isSubmitting, setIsSubmitting] = React.useState<boolean>(false);
React.useEffect(
() => {
if (isSubmitting && isTopicCreated) {
const {name} = getValues();
redirectToTopicPath(clusterName, name);
}
},
[isSubmitting, isTopicCreated, redirectToTopicPath, clusterName, getValues],
);
const onSubmit = async (data: TopicFormData) => {
//TODO: need to fix loader. After success loading the first time, we won't wait for creation any more, because state is
//loaded, and we will try to get entity immediately after pressing the button, and we will receive null
//going to object page on the second creation. Resetting loaded state is workaround, need to tweak loader logic
resetUploadedState();
setIsSubmitting(true);
createTopic(clusterName, data);
};
return (
<div className="section">
<div className="level">
<div className="level-item level-left">
<Breadcrumb links={[
{href: clusterTopicsPath(clusterName), label: 'All Topics'},
]}>
New Topic
</Breadcrumb>
</div>
</div>
<div className="box">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="columns">
<div className="column is-three-quarters">
<label className="label">
Topic Name *
</label>
<input
className="input"
placeholder="Topic Name"
ref={register({
required: 'Topic Name is required.',
pattern: {
value: TOPIC_NAME_VALIDATION_PATTERN,
message: 'Only alphanumeric, _, -, and . allowed',
},
})}
name="name"
autoComplete="off"
disabled={isSubmitting}
/>
<p className="help is-danger">
<ErrorMessage errors={errors} name="name"/>
</p>
</div>
<div className="column">
<label className="label">
Number of partitions *
</label>
<input
className="input"
type="number"
placeholder="Number of partitions"
defaultValue="1"
ref={register({required: 'Number of partitions is required.'})}
name="partitions"
disabled={isSubmitting}
/>
<p className="help is-danger">
<ErrorMessage errors={errors} name="partitions"/>
</p>
</div>
</div>
<div className="columns">
<div className="column">
<label className="label">
Replication Factor *
</label>
<input
className="input"
type="number"
placeholder="Replication Factor"
defaultValue="1"
ref={register({required: 'Replication Factor is required.'})}
name="replicationFactor"
disabled={isSubmitting}
/>
<p className="help is-danger">
<ErrorMessage errors={errors} name="replicationFactor"/>
</p>
</div>
<div className="column">
<label className="label">
Min In Sync Replicas *
</label>
<input
className="input"
type="number"
placeholder="Replication Factor"
defaultValue="1"
ref={register({required: 'Min In Sync Replicas is required.'})}
name="minInSyncReplicas"
disabled={isSubmitting}
/>
<p className="help is-danger">
<ErrorMessage errors={errors} name="minInSyncReplicas"/>
</p>
</div>
</div>
<div className="columns">
<div className="column is-one-third">
<label className="label">
Cleanup policy
</label>
<div className="select is-block">
<select
defaultValue={CleanupPolicy.Delete}
name="cleanupPolicy"
ref={register}
disabled={isSubmitting}
>
<option value={CleanupPolicy.Delete}>
Delete
</option>
<option value={CleanupPolicy.Compact}>
Compact
</option>
</select>
</div>
</div>
<div className="column is-one-third">
<label className="label">
Time to retain data
</label>
<div className="select is-block">
<select
defaultValue={MILLISECONDS_IN_DAY * 7}
name="retentionMs"
ref={register}
disabled={isSubmitting}
>
<option value={MILLISECONDS_IN_DAY / 2}>
12 hours
</option>
<option value={MILLISECONDS_IN_DAY}>
1 day
</option>
<option value={MILLISECONDS_IN_DAY * 2}>
2 days
</option>
<option value={MILLISECONDS_IN_DAY * 7}>
1 week
</option>
<option value={MILLISECONDS_IN_DAY * 7 * 4}>
4 weeks
</option>
</select>
</div>
</div>
<div className="column is-one-third">
<label className="label">
Max size on disk in GB
</label>
<div className="select is-block">
<select
defaultValue={-1}
name="retentionBytes"
ref={register}
disabled={isSubmitting}
>
<option value={-1}>
Not Set
</option>
<option value={BYTES_IN_GB}>
1 GB
</option>
<option value={BYTES_IN_GB * 10}>
10 GB
</option>
<option value={BYTES_IN_GB * 20}>
20 GB
</option>
<option value={BYTES_IN_GB * 50}>
50 GB
</option>
</select>
</div>
</div>
</div>
<div className="columns">
<div className="column">
<label className="label">
Maximum message size in bytes *
</label>
<input
className="input"
type="number"
defaultValue="1000012"
ref={register({required: 'Maximum message size in bytes is required'})}
name="maxMessageBytes"
disabled={isSubmitting}
/>
<p className="help is-danger">
<ErrorMessage errors={errors} name="maxMessageBytes"/>
</p>
</div>
</div>
<input type="submit" className="button is-primary" disabled={isSubmitting}/>
</form>
</div>
</div>
);
};
export default New;