Sergey Zakirov před 5 roky
rodič
revize
3ba6076cbc
23 změnil soubory, kde provedl 69 přidání a 732 odebrání
  1. 0 20
      kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamAction.tsx
  2. 0 33
      kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamButton.tsx
  3. 0 20
      kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamOptions.tsx
  4. 0 59
      kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamSelect.tsx
  5. 0 54
      kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamValue.tsx
  6. 0 87
      kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParams.tsx
  7. 0 18
      kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamsContainer.tsx
  8. 0 96
      kafka-ui-react-app/src/components/Topics/New/CustomParams/customParamsOptions.tsx
  9. 9 172
      kafka-ui-react-app/src/components/Topics/New/New.tsx
  10. 0 52
      kafka-ui-react-app/src/components/Topics/New/TimeToRetain.tsx
  11. 0 29
      kafka-ui-react-app/src/components/Topics/New/TimeToRetainBtn.tsx
  12. 0 36
      kafka-ui-react-app/src/components/Topics/New/TimeToRetainBtns.tsx
  13. 1 1
      kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamOptions.tsx
  14. 2 2
      kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamValue.tsx
  15. 0 3
      kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParams.tsx
  16. 4 2
      kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/customParamsOptions.tsx
  17. 3 1
      kafka-ui-react-app/src/redux/actionType.ts
  18. 1 1
      kafka-ui-react-app/src/redux/actions/actions.ts
  19. 5 1
      kafka-ui-react-app/src/redux/api/topics.ts
  20. 9 6
      kafka-ui-react-app/src/redux/reducers/brokers/reducer.ts
  21. 1 1
      kafka-ui-react-app/src/redux/reducers/clusters/reducer.ts
  22. 19 20
      kafka-ui-react-app/src/redux/reducers/consumerGroups/reducer.ts
  23. 15 18
      kafka-ui-react-app/src/redux/reducers/topics/reducer.ts

+ 0 - 20
kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamAction.tsx

@@ -1,20 +0,0 @@
-import React from 'react';
-import CustomParamButton, { CustomParamButtonType } from './CustomParamButton';
-
-interface Props {
-  index: string;
-  onRemove: (index: string) => void;
-}
-
-const CustomParamAction: React.FC<Props> = ({ index, onRemove }) => (
-  <>
-    <label className="label">&nbsp;</label>
-    <CustomParamButton
-      className="is-danger"
-      type={CustomParamButtonType.minus}
-      onClick={() => onRemove(index)}
-    />
-  </>
-);
-
-export default CustomParamAction;

+ 0 - 33
kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamButton.tsx

@@ -1,33 +0,0 @@
-import React from 'react';
-
-export enum CustomParamButtonType {
-  plus = 'fa-plus',
-  minus = 'fa-minus',
-}
-
-interface Props {
-  onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
-  className: string;
-  type: CustomParamButtonType;
-  btnText?: string;
-}
-
-const CustomParamButton: React.FC<Props> = ({
-  onClick,
-  className,
-  type,
-  btnText,
-}) => (
-  <button
-    type="button"
-    className={`button ${className} is-outlined`}
-    onClick={onClick}
-  >
-    {btnText && <span>{btnText}</span>}
-    <span className="icon">
-      <i className={`fas fa-lg ${type}`} />
-    </span>
-  </button>
-);
-
-export default CustomParamButton;

+ 0 - 20
kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamOptions.tsx

@@ -1,20 +0,0 @@
-import React from 'react';
-import { TopicCustomParamOption } from 'redux/interfaces';
-import { CUSTOM_PARAMS_OPTIONS } from './customParamsOptions';
-
-interface Props {};
-
-const CustomParamOptions: React.FC<Props> = () => (
-  <>
-    <option value=''>Select</option>
-    {
-      Object.values(CUSTOM_PARAMS_OPTIONS).map((opt: TopicCustomParamOption) => (
-        <option key={opt.name} value={opt.name}>
-          {opt.name}
-        </option>
-      ))
-    }
-  </>
-);
-
-export default React.memo(CustomParamOptions);

+ 0 - 59
kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamSelect.tsx

@@ -1,59 +0,0 @@
-import React from 'react';
-import { useFormContext, ErrorMessage } from 'react-hook-form';
-import { TopicFormCustomParam } from 'redux/interfaces';
-import CustomParamOptions from './CustomParamOptions';
-import { INDEX_PREFIX } from './CustomParams';
-
-interface Props {
-  isDisabled: boolean;
-  index: string;
-  name: string;
-}
-
-const CustomParamSelect: React.FC<Props> = ({ isDisabled, index, name }) => {
-  const { register, errors, getValues, triggerValidation } = useFormContext();
-  const optInputName = `${index}[name]`;
-
-  const selectedMustBeUniq = (selected: string) => {
-    const values = getValues({ nest: true });
-    const customParamsValues: TopicFormCustomParam = values.customParams;
-
-    let valid = true;
-
-    for (const [key, customParam] of Object.entries(customParamsValues)) {
-      if (`${INDEX_PREFIX}.${key}` !== index) {
-        if (selected === customParam.name) {
-          valid = false;
-          break;
-        }
-      }
-    }
-
-    return valid ? true : 'Custom Parameter must be unique';
-  };
-
-  return (
-    <>
-      <label className="label">Custom Parameter</label>
-      <div className="select is-block">
-        <select
-          name={optInputName}
-          ref={register({
-            required: 'Custom Parameter is required.',
-            validate: { unique: (selected) => selectedMustBeUniq(selected) },
-          })}
-          onChange={() => triggerValidation(optInputName)}
-          disabled={isDisabled}
-          defaultValue={name}
-        >
-          <CustomParamOptions />
-        </select>
-        <p className="help is-danger">
-          <ErrorMessage errors={errors} name={optInputName} />
-        </p>
-      </div>
-    </>
-  );
-};
-
-export default React.memo(CustomParamSelect);

+ 0 - 54
kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamValue.tsx

@@ -1,54 +0,0 @@
-import React from 'react';
-import { useFormContext, ErrorMessage } from 'react-hook-form';
-import { CUSTOM_PARAMS_OPTIONS } from './customParamsOptions';
-
-interface Props {
-  isDisabled: boolean;
-  index: string;
-  name: string;
-  defaultValue: string;
-}
-
-const CustomParamValue: React.FC<Props> = ({
-  isDisabled,
-  index,
-  name,
-  defaultValue,
-}) => {
-  const { register, errors, watch, setValue } = useFormContext();
-  const selectInputName = `${index}[name]`;
-  const valInputName = `${index}[value]`;
-  const selectedParamName = watch(selectInputName, name);
-
-  React.useEffect(() => {
-    if (selectedParamName) {
-      setValue(
-        valInputName,
-        CUSTOM_PARAMS_OPTIONS[selectedParamName].defaultValue,
-        true
-      );
-    }
-  }, [selectedParamName]);
-
-  return (
-    <>
-      <label className="label">Value</label>
-      <input
-        className="input"
-        placeholder="Value"
-        ref={register({
-          required: 'Value is required.',
-        })}
-        name={valInputName}
-        defaultValue={defaultValue}
-        autoComplete="off"
-        disabled={isDisabled}
-      />
-      <p className="help is-danger">
-        <ErrorMessage errors={errors} name={valInputName} />
-      </p>
-    </>
-  );
-};
-
-export default React.memo(CustomParamValue);

+ 0 - 87
kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParams.tsx

@@ -1,87 +0,0 @@
-import React from 'react';
-import { omit, reject } from 'lodash';
-
-import { TopicFormCustomParams } from 'redux/interfaces';
-import CustomParamSelect from './CustomParamSelect';
-import CustomParamValue from './CustomParamValue';
-import CustomParamAction from './CustomParamAction';
-import CustomParamButton, { CustomParamButtonType } from './CustomParamButton';
-
-export const INDEX_PREFIX = 'customParams';
-
-interface Props {
-  isSubmitting: boolean;
-}
-
-const CustomParams: React.FC<Props> = ({ isSubmitting }) => {
-  const [formCustomParams, setFormCustomParams] = React.useState<
-    TopicFormCustomParams
-  >({
-    byIndex: {},
-    allIndexes: [],
-  });
-
-  const onAdd = (event: React.MouseEvent<HTMLButtonElement>) => {
-    event.preventDefault();
-
-    const newIndex = `${INDEX_PREFIX}.${new Date().getTime()}ts`;
-
-    setFormCustomParams({
-      ...formCustomParams,
-      byIndex: {
-        ...formCustomParams.byIndex,
-        [newIndex]: { name: '', value: '' },
-      },
-      allIndexes: [newIndex, ...formCustomParams.allIndexes],
-    });
-  };
-
-  const onRemove = (index: string) => {
-    setFormCustomParams({
-      ...formCustomParams,
-      byIndex: omit(formCustomParams.byIndex, index),
-      allIndexes: reject(formCustomParams.allIndexes, (i) => i === index),
-    });
-  };
-
-  return (
-    <>
-      <div className="columns">
-        <div className="column">
-          <CustomParamButton
-            className="is-success"
-            type={CustomParamButtonType.plus}
-            onClick={onAdd}
-            btnText="Add Custom Parameter"
-          />
-        </div>
-      </div>
-      {formCustomParams.allIndexes.map((index) => (
-        <div className="columns is-centered" key={index}>
-          <div className="column">
-            <CustomParamSelect
-              index={index}
-              isDisabled={isSubmitting}
-              name={formCustomParams.byIndex[index].name}
-            />
-          </div>
-
-          <div className="column">
-            <CustomParamValue
-              index={index}
-              isDisabled={isSubmitting}
-              name={formCustomParams.byIndex[index].name}
-              defaultValue={formCustomParams.byIndex[index].value}
-            />
-          </div>
-
-          <div className="column is-narrow">
-            <CustomParamAction index={index} onRemove={onRemove} />
-          </div>
-        </div>
-      ))}
-    </>
-  );
-};
-
-export default CustomParams;

+ 0 - 18
kafka-ui-react-app/src/components/Topics/New/CustomParams/CustomParamsContainer.tsx

@@ -1,18 +0,0 @@
-import { connect } from 'react-redux';
-import { RootState } from 'redux/interfaces';
-import { withRouter, RouteComponentProps } from 'react-router-dom';
-import CustomParams from './CustomParams';
-
-interface RouteProps {};
-
-interface OwnProps extends RouteComponentProps<RouteProps> {
-  isSubmitting: boolean;
-}
-
-const mapStateToProps = (state: RootState, { isSubmitting }: OwnProps) => ({
-  isSubmitting,
-})
-
-export default withRouter(
-  connect(mapStateToProps)(CustomParams)
-);

+ 0 - 96
kafka-ui-react-app/src/components/Topics/New/CustomParams/customParamsOptions.tsx

@@ -1,96 +0,0 @@
-import { TopicCustomParamOption } from 'redux/interfaces';
-
-interface CustomParamOption {
-  [optionName: string]: TopicCustomParamOption;
-}
-
-export const CUSTOM_PARAMS_OPTIONS: CustomParamOption = {
-  "compression.type": {
-    "name": "compression.type",
-    "defaultValue": "producer"
-  },
-  "leader.replication.throttled.replicas": {
-    "name": "leader.replication.throttled.replicas",
-    "defaultValue": ""
-  },
-  "message.downconversion.enable": {
-    "name": "message.downconversion.enable",
-    "defaultValue": "true"
-  },
-  "segment.jitter.ms": {
-    "name": "segment.jitter.ms",
-    "defaultValue": "0"
-  },
-  "flush.ms": {
-    "name": "flush.ms",
-    "defaultValue": "9223372036854775807"
-  },
-  "follower.replication.throttled.replicas": {
-    "name": "follower.replication.throttled.replicas",
-    "defaultValue": ""
-  },
-  "segment.bytes": {
-    "name": "segment.bytes",
-    "defaultValue": "1073741824"
-  },
-  "flush.messages": {
-    "name": "flush.messages",
-    "defaultValue": "9223372036854775807"
-  },
-  "message.format.version": {
-    "name": "message.format.version",
-    "defaultValue": "2.3-IV1"
-  },
-  "file.delete.delay.ms": {
-    "name": "file.delete.delay.ms",
-    "defaultValue": "60000"
-  },
-  "max.compaction.lag.ms": {
-    "name": "max.compaction.lag.ms",
-    "defaultValue": "9223372036854775807"
-  },
-  "min.compaction.lag.ms": {
-    "name": "min.compaction.lag.ms",
-    "defaultValue": "0"
-  },
-  "message.timestamp.type": {
-    "name": "message.timestamp.type",
-    "defaultValue": "CreateTime"
-  },
-  "preallocate": {
-    "name": "preallocate",
-    "defaultValue": "false"
-  },
-  "min.cleanable.dirty.ratio": {
-    "name": "min.cleanable.dirty.ratio",
-    "defaultValue": "0.5"
-  },
-  "index.interval.bytes": {
-    "name": "index.interval.bytes",
-    "defaultValue": "4096"
-  },
-  "unclean.leader.election.enable": {
-    "name": "unclean.leader.election.enable",
-    "defaultValue": "true"
-  },
-  "retention.bytes": {
-    "name": "retention.bytes",
-    "defaultValue": "-1"
-  },
-  "delete.retention.ms": {
-    "name": "delete.retention.ms",
-    "defaultValue": "86400000"
-  },
-  "segment.ms": {
-    "name": "segment.ms",
-    "defaultValue": "604800000"
-  },
-  "message.timestamp.difference.max.ms": {
-    "name": "message.timestamp.difference.max.ms",
-    "defaultValue": "9223372036854775807"
-  },
-  "segment.index.bytes": {
-    "name": "segment.index.bytes",
-    "defaultValue": "10485760"
-  }
-}

+ 9 - 172
kafka-ui-react-app/src/components/Topics/New/New.tsx

@@ -1,17 +1,10 @@
 import React from 'react';
-import {
-  ClusterName,
-  CleanupPolicy,
-  TopicFormData,
-  TopicName,
-} from 'redux/interfaces';
-import { useForm, FormContext, ErrorMessage } from 'react-hook-form';
+import { ClusterName, TopicFormData, TopicName } from 'redux/interfaces';
+import { useForm, FormContext } from 'react-hook-form';
 
 import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
 import { clusterTopicsPath } from 'lib/paths';
-import { TOPIC_NAME_VALIDATION_PATTERN, BYTES_IN_GB } from 'lib/constants';
-import CustomParamsContainer from './CustomParams/CustomParamsContainer';
-import TimeToRetain from './TimeToRetain';
+import TopicForm from 'components/Topics/shared/Form/TopicForm';
 
 interface Props {
   clusterName: ClusterName;
@@ -36,13 +29,7 @@ const New: React.FC<Props> = ({
       const { name } = methods.getValues();
       redirectToTopicPath(clusterName, name);
     }
-  }, [
-    isSubmitting,
-    isTopicCreated,
-    redirectToTopicPath,
-    clusterName,
-    methods.getValues,
-  ]);
+  }, [isSubmitting, isTopicCreated, redirectToTopicPath, clusterName, methods]);
 
   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
@@ -70,161 +57,11 @@ const New: React.FC<Props> = ({
       <div className="box">
         {/* eslint-disable react/jsx-props-no-spreading */}
         <FormContext {...methods}>
-          <form onSubmit={methods.handleSubmit(onSubmit)}>
-            <div className="columns">
-              <div className="column is-three-quarters">
-                <label className="label">Topic Name *</label>
-                <input
-                  className="input"
-                  placeholder="Topic Name"
-                  ref={methods.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={methods.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={methods.register({
-                    required: 'Number of partitions is required.',
-                  })}
-                  name="partitions"
-                  disabled={isSubmitting}
-                />
-                <p className="help is-danger">
-                  <ErrorMessage errors={methods.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={methods.register({
-                    required: 'Replication Factor is required.',
-                  })}
-                  name="replicationFactor"
-                  disabled={isSubmitting}
-                />
-                <p className="help is-danger">
-                  <ErrorMessage
-                    errors={methods.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={methods.register({
-                    required: 'Min In Sync Replicas is required.',
-                  })}
-                  name="minInSyncReplicas"
-                  disabled={isSubmitting}
-                />
-                <p className="help is-danger">
-                  <ErrorMessage
-                    errors={methods.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={methods.register}
-                    disabled={isSubmitting}
-                  >
-                    <option value={CleanupPolicy.Delete}>Delete</option>
-                    <option value={CleanupPolicy.Compact}>Compact</option>
-                  </select>
-                </div>
-              </div>
-
-              <div className="column is-one-third">
-                <TimeToRetain isSubmitting={isSubmitting} />
-              </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={methods.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={methods.register({
-                    required: 'Maximum message size in bytes is required',
-                  })}
-                  name="maxMessageBytes"
-                  disabled={isSubmitting}
-                />
-                <p className="help is-danger">
-                  <ErrorMessage
-                    errors={methods.errors}
-                    name="maxMessageBytes"
-                  />
-                </p>
-              </div>
-            </div>
-
-            <CustomParamsContainer isSubmitting={isSubmitting} />
-
-            <input
-              type="submit"
-              className="button is-primary"
-              disabled={isSubmitting}
-            />
-          </form>
+          <TopicForm
+            isSubmitting={isSubmitting}
+            isEditing
+            onSubmit={methods.handleSubmit(onSubmit)}
+          />
         </FormContext>
       </div>
     </div>

+ 0 - 52
kafka-ui-react-app/src/components/Topics/New/TimeToRetain.tsx

@@ -1,52 +0,0 @@
-import React from 'react';
-import prettyMilliseconds from 'pretty-ms';
-import { useFormContext, ErrorMessage } from 'react-hook-form';
-import { MILLISECONDS_IN_WEEK, MILLISECONDS_IN_SECOND } from 'lib/constants';
-import TimeToRetainBtns from './TimeToRetainBtns';
-
-interface Props {
-  isSubmitting: boolean;
-}
-
-const TimeToRetain: React.FC<Props> = ({ isSubmitting }) => {
-  const { register, errors, watch } = useFormContext();
-  const defaultValue = MILLISECONDS_IN_WEEK;
-  const name = 'retentionMs';
-  const watchedValue = watch(name, defaultValue.toString());
-
-  const valueHint = React.useMemo(() => {
-    const value = parseInt(watchedValue, 10);
-    return value >= MILLISECONDS_IN_SECOND ? prettyMilliseconds(value) : false;
-  }, [watchedValue]);
-
-  return (
-    <>
-      <label
-        className="label is-flex"
-        style={{ justifyContent: 'space-between' }}
-      >
-        <div>Time to retain data (in ms)</div>
-        {valueHint && <span className="has-text-info">{valueHint}</span>}
-      </label>
-      <input
-        className="input"
-        id="timeToRetain"
-        type="number"
-        defaultValue={defaultValue}
-        name={name}
-        ref={register({
-          min: { value: -1, message: 'must be greater than or equal to -1' },
-        })}
-        disabled={isSubmitting}
-      />
-
-      <p className="help is-danger">
-        <ErrorMessage errors={errors} name={name} />
-      </p>
-
-      <TimeToRetainBtns name={name} value={watchedValue} />
-    </>
-  );
-};
-
-export default TimeToRetain;

+ 0 - 29
kafka-ui-react-app/src/components/Topics/New/TimeToRetainBtn.tsx

@@ -1,29 +0,0 @@
-import React from 'react';
-import { useFormContext } from 'react-hook-form';
-import cx from 'classnames';
-import { MILLISECONDS_IN_WEEK } from 'lib/constants';
-
-interface Props {
-  inputName: string;
-  text: string;
-  value: number;
-}
-
-const TimeToRetainBtn: React.FC<Props> = ({ inputName, text, value }) => {
-  const { setValue, watch } = useFormContext();
-  const watchedValue = watch(inputName, MILLISECONDS_IN_WEEK.toString());
-
-  return (
-    <button
-      type="button"
-      className={cx('button', {
-        'is-info': watchedValue === value.toString(),
-      })}
-      onClick={() => setValue(inputName, value)}
-    >
-      {text}
-    </button>
-  );
-};
-
-export default TimeToRetainBtn;

+ 0 - 36
kafka-ui-react-app/src/components/Topics/New/TimeToRetainBtns.tsx

@@ -1,36 +0,0 @@
-import React from 'react';
-import { MILLISECONDS_IN_DAY } from 'lib/constants';
-import TimeToRetainBtn from './TimeToRetainBtn';
-
-interface Props {
-  name: string;
-  value: string;
-}
-
-const TimeToRetainBtns: React.FC<Props> = ({ name }) => (
-  <div className="buttons are-small">
-    <TimeToRetainBtn
-      text="12h"
-      inputName={name}
-      value={MILLISECONDS_IN_DAY / 2}
-    />
-    <TimeToRetainBtn text="1d" inputName={name} value={MILLISECONDS_IN_DAY} />
-    <TimeToRetainBtn
-      text="2d"
-      inputName={name}
-      value={MILLISECONDS_IN_DAY * 2}
-    />
-    <TimeToRetainBtn
-      text="7d"
-      inputName={name}
-      value={MILLISECONDS_IN_DAY * 7}
-    />
-    <TimeToRetainBtn
-      text="4w"
-      inputName={name}
-      value={MILLISECONDS_IN_DAY * 7 * 24}
-    />
-  </div>
-);
-
-export default TimeToRetainBtns;

+ 1 - 1
kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamOptions.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import { TopicCustomParamOption } from 'redux/interfaces';
-import { CUSTOM_PARAMS_OPTIONS } from './customParamsOptions';
+import CUSTOM_PARAMS_OPTIONS from './customParamsOptions';
 
 const CustomParamOptions = () => (
   <>

+ 2 - 2
kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamValue.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import { useFormContext, ErrorMessage } from 'react-hook-form';
-import { CUSTOM_PARAMS_OPTIONS } from './customParamsOptions';
+import CUSTOM_PARAMS_OPTIONS from './customParamsOptions';
 
 interface Props {
   isDisabled: boolean;
@@ -28,7 +28,7 @@ const CustomParamValue: React.FC<Props> = ({
         true
       );
     }
-  }, [selectedParamName]);
+  }, [selectedParamName, setValue, valInputName]);
 
   return (
     <>

+ 0 - 3
kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParams.tsx

@@ -22,7 +22,6 @@ interface Param {
 }
 
 const CustomParams: React.FC<Props> = ({ isSubmitting, config }) => {
-  /* eslint-disable no-param-reassign */
   const byIndex = config
     ? reduce(
         config.byName,
@@ -44,8 +43,6 @@ const CustomParams: React.FC<Props> = ({ isSubmitting, config }) => {
     allIndexes: Object.keys(byIndex),
   });
 
-  console.log(byIndex);
-
   const onAdd = (event: React.MouseEvent<HTMLButtonElement>) => {
     event.preventDefault();
 

+ 4 - 2
kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/customParamsOptions.tsx

@@ -1,10 +1,10 @@
 import { TopicCustomParamOption } from 'redux/interfaces';
 
-export interface CustomParamOption {
+interface CustomParamOption {
   [optionName: string]: TopicCustomParamOption;
 }
 
-export const CUSTOM_PARAMS_OPTIONS: CustomParamOption = {
+const CUSTOM_PARAMS_OPTIONS: CustomParamOption = {
   'compression.type': {
     name: 'compression.type',
     defaultValue: 'producer',
@@ -94,3 +94,5 @@ export const CUSTOM_PARAMS_OPTIONS: CustomParamOption = {
     defaultValue: '10485760',
   },
 };
+
+export default CUSTOM_PARAMS_OPTIONS;

+ 3 - 1
kafka-ui-react-app/src/redux/actionType.ts

@@ -1,4 +1,4 @@
-export enum ActionType {
+enum ActionType {
   GET_CLUSTERS__REQUEST = 'GET_CLUSTERS__REQUEST',
   GET_CLUSTERS__SUCCESS = 'GET_CLUSTERS__SUCCESS',
   GET_CLUSTERS__FAILURE = 'GET_CLUSTERS__FAILURE',
@@ -39,3 +39,5 @@ export enum ActionType {
   GET_CONSUMER_GROUP_DETAILS__SUCCESS = 'GET_CONSUMER_GROUP_DETAILS__SUCCESS',
   GET_CONSUMER_GROUP_DETAILS__FAILURE = 'GET_CONSUMER_GROUP_DETAILS__FAILURE',
 }
+
+export default ActionType;

+ 1 - 1
kafka-ui-react-app/src/redux/actions/actions.ts

@@ -1,5 +1,5 @@
 import { createAsyncAction } from 'typesafe-actions';
-import { ActionType } from 'redux/actionType';
+import ActionType from 'redux/actionType';
 import {
   Broker,
   BrokerMetrics,

+ 5 - 1
kafka-ui-react-app/src/redux/api/topics.ts

@@ -15,7 +15,11 @@ interface TopicFormParams {
 
 const formatParams = (params: TopicFormData, omittedFields: string[] = []) => {
   return Object.keys(params).reduce((result, paramName) => {
-    if (omittedFields.includes(paramName)) {
+    if (
+      ['name', 'partitions', 'replicationFactor', ...omittedFields].includes(
+        paramName
+      )
+    ) {
       return result;
     }
     result[snakeCase(paramName).replace(/_/g, '.')] = params[

+ 9 - 6
kafka-ui-react-app/src/redux/reducers/brokers/reducer.ts

@@ -4,11 +4,9 @@ import {
   ZooKeeperStatus,
   BrokerMetrics,
 } from 'redux/interfaces';
-import {
-  ActionType,
-} from 'redux/actionType';
+import ActionType from 'redux/actionType';
 
-export const initialState: BrokersState =  {
+export const initialState: BrokersState = {
   items: [],
   brokerCount: 0,
   zooKeeperStatus: ZooKeeperStatus.offline,
@@ -21,12 +19,17 @@ export const initialState: BrokersState =  {
   diskUsage: [],
 };
 
-const updateBrokerSegmentSize = (state: BrokersState, payload: BrokerMetrics) => {
+const updateBrokerSegmentSize = (
+  state: BrokersState,
+  payload: BrokerMetrics
+) => {
   const brokers = state.items;
   const { diskUsage } = payload;
 
   const items = brokers.map((broker) => {
-    const brokerMetrics = diskUsage.find(({ brokerId }) => brokerId === broker.brokerId);
+    const brokerMetrics = diskUsage.find(
+      ({ brokerId }) => brokerId === broker.brokerId
+    );
     if (brokerMetrics !== undefined) {
       return { ...broker, ...brokerMetrics };
     }

+ 1 - 1
kafka-ui-react-app/src/redux/reducers/clusters/reducer.ts

@@ -1,5 +1,5 @@
 import { Cluster, Action } from 'redux/interfaces';
-import { ActionType } from 'redux/actionType';
+import ActionType from 'redux/actionType';
 
 export const initialState: Cluster[] = [];
 

+ 19 - 20
kafka-ui-react-app/src/redux/reducers/consumerGroups/reducer.ts

@@ -1,31 +1,30 @@
-import { Action, ConsumerGroup } from 'redux/interfaces';
-import { ActionType } from 'redux/actionType';
-import { ConsumerGroupsState } from '../../interfaces/consumerGroup';
+import { Action, ConsumerGroup, ConsumerGroupsState } from 'redux/interfaces';
+import ActionType from 'redux/actionType';
 
 export const initialState: ConsumerGroupsState = {
   byID: {},
-  allIDs: []
+  allIDs: [],
 };
 
-const updateConsumerGroupsList = (state: ConsumerGroupsState, payload: ConsumerGroup[]): ConsumerGroupsState => {
+const updateConsumerGroupsList = (
+  state: ConsumerGroupsState,
+  payload: ConsumerGroup[]
+): ConsumerGroupsState => {
   const initialMemo: ConsumerGroupsState = {
     ...state,
-    allIDs: []
+    allIDs: [],
   };
 
-  return payload.reduce(
-    (memo: ConsumerGroupsState, consumerGroup) => {
-      const {consumerGroupId} = consumerGroup;
-      memo.byID[consumerGroupId] = {
-        ...memo.byID[consumerGroupId],
-        ...consumerGroup,
-      };
-      memo.allIDs.push(consumerGroupId);
+  return payload.reduce((memo: ConsumerGroupsState, consumerGroup) => {
+    const { consumerGroupId } = consumerGroup;
+    memo.byID[consumerGroupId] = {
+      ...memo.byID[consumerGroupId],
+      ...consumerGroup,
+    };
+    memo.allIDs.push(consumerGroupId);
 
-      return memo;
-    },
-    initialMemo,
-  );
+    return memo;
+  }, initialMemo);
 };
 
 const reducer = (state = initialState, action: Action): ConsumerGroupsState => {
@@ -40,8 +39,8 @@ const reducer = (state = initialState, action: Action): ConsumerGroupsState => {
           [action.payload.consumerGroupID]: {
             ...state.byID[action.payload.consumerGroupID],
             ...action.payload.details,
-          }
-        }
+          },
+        },
       };
     default:
       return state;

+ 15 - 18
kafka-ui-react-app/src/redux/reducers/topics/reducer.ts

@@ -1,5 +1,5 @@
 import { Action, TopicsState, Topic } from 'redux/interfaces';
-import { ActionType } from 'redux/actionType';
+import ActionType from 'redux/actionType';
 
 export const initialState: TopicsState = {
   byName: {},
@@ -12,24 +12,21 @@ const updateTopicList = (state: TopicsState, payload: Topic[]): TopicsState => {
     allNames: [],
   };
 
-  return payload.reduce(
-    (memo: TopicsState, topic) => {
-      const {name} = topic;
-      memo.byName[name] = {
-        ...memo.byName[name],
-        ...topic,
-      };
-      memo.allNames.push(name);
+  return payload.reduce((memo: TopicsState, topic) => {
+    const { name } = topic;
+    memo.byName[name] = {
+      ...memo.byName[name],
+      ...topic,
+    };
+    memo.allNames.push(name);
 
-      return memo;
-    },
-    initialMemo,
-  );
+    return memo;
+  }, initialMemo);
 };
 
 const addToTopicList = (state: TopicsState, payload: Topic): TopicsState => {
   const newState: TopicsState = {
-    ...state
+    ...state,
   };
   newState.allNames.push(payload.name);
   newState.byName[payload.name] = payload;
@@ -48,8 +45,8 @@ const reducer = (state = initialState, action: Action): TopicsState => {
           [action.payload.topicName]: {
             ...state.byName[action.payload.topicName],
             ...action.payload.details,
-          }
-        }
+          },
+        },
       };
     case ActionType.GET_TOPIC_CONFIG__SUCCESS:
       return {
@@ -59,8 +56,8 @@ const reducer = (state = initialState, action: Action): TopicsState => {
           [action.payload.topicName]: {
             ...state.byName[action.payload.topicName],
             config: action.payload.config,
-          }
-        }
+          },
+        },
       };
     case ActionType.POST_TOPIC__SUCCESS:
       return addToTopicList(state, action.payload);