Edit.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import React from 'react';
  2. import {
  3. ClusterName,
  4. TopicFormDataRaw,
  5. TopicName,
  6. TopicConfigByName,
  7. TopicWithDetailedInfo,
  8. } from 'redux/interfaces';
  9. import { TopicConfig } from 'generated-sources';
  10. import { useForm, FormProvider } from 'react-hook-form';
  11. import { camelCase } from 'lodash';
  12. import TopicForm from 'components/Topics/shared/Form/TopicForm';
  13. import { clusterTopicPath } from 'lib/paths';
  14. import { useHistory } from 'react-router';
  15. import DangerZoneContainer from './DangerZoneContainer';
  16. interface Props {
  17. clusterName: ClusterName;
  18. topicName: TopicName;
  19. topic?: TopicWithDetailedInfo;
  20. isFetched: boolean;
  21. isTopicUpdated: boolean;
  22. fetchTopicConfig: (clusterName: ClusterName, topicName: TopicName) => void;
  23. updateTopic: (
  24. clusterName: ClusterName,
  25. topicName: TopicName,
  26. form: TopicFormDataRaw
  27. ) => void;
  28. updateTopicPartitionsCount: (
  29. clusterName: string,
  30. topicname: string,
  31. partitions: number
  32. ) => void;
  33. }
  34. const DEFAULTS = {
  35. partitions: 1,
  36. replicationFactor: 1,
  37. minInSyncReplicas: 1,
  38. cleanupPolicy: 'delete',
  39. retentionBytes: -1,
  40. maxMessageBytes: 1000012,
  41. };
  42. const topicParams = (topic: TopicWithDetailedInfo | undefined) => {
  43. if (!topic) {
  44. return DEFAULTS;
  45. }
  46. const { name, replicationFactor } = topic;
  47. const configs = topic.config?.reduce(
  48. (result: { [key: string]: TopicConfig['value'] }, param) => ({
  49. ...result,
  50. [camelCase(param.name)]: param.value || param.defaultValue,
  51. }),
  52. {}
  53. );
  54. return {
  55. ...DEFAULTS,
  56. name,
  57. partitions: topic.partitionCount || DEFAULTS.partitions,
  58. replicationFactor,
  59. ...configs,
  60. };
  61. };
  62. let formInit = false;
  63. const Edit: React.FC<Props> = ({
  64. clusterName,
  65. topicName,
  66. topic,
  67. isFetched,
  68. isTopicUpdated,
  69. fetchTopicConfig,
  70. updateTopic,
  71. }) => {
  72. const defaultValues = topicParams(topic);
  73. const methods = useForm<TopicFormDataRaw>({ defaultValues });
  74. const [isSubmitting, setIsSubmitting] = React.useState<boolean>(false);
  75. const history = useHistory();
  76. React.useEffect(() => {
  77. fetchTopicConfig(clusterName, topicName);
  78. }, [fetchTopicConfig, clusterName, topicName]);
  79. React.useEffect(() => {
  80. if (isSubmitting && isTopicUpdated) {
  81. const { name } = methods.getValues();
  82. history.push(clusterTopicPath(clusterName, name));
  83. }
  84. }, [isSubmitting, isTopicUpdated, clusterTopicPath, clusterName, methods]);
  85. if (!isFetched || !topic || !topic.config) {
  86. return null;
  87. }
  88. if (!formInit) {
  89. methods.reset(defaultValues);
  90. formInit = true;
  91. }
  92. const config: TopicConfigByName = {
  93. byName: {},
  94. };
  95. topic.config.forEach((param) => {
  96. config.byName[param.name] = param;
  97. });
  98. const onSubmit = async (data: TopicFormDataRaw) => {
  99. updateTopic(clusterName, topicName, data);
  100. setIsSubmitting(true); // Keep this action after updateTopic to prevent redirect before update.
  101. };
  102. return (
  103. <div>
  104. <div className="box">
  105. <FormProvider {...methods}>
  106. <TopicForm
  107. topicName={topicName}
  108. config={config}
  109. isSubmitting={isSubmitting}
  110. isEditing
  111. onSubmit={methods.handleSubmit(onSubmit)}
  112. />
  113. </FormProvider>
  114. </div>
  115. {topic && (
  116. <DangerZoneContainer
  117. defaultPartitions={defaultValues.partitions}
  118. defaultReplicationFactor={
  119. defaultValues.replicationFactor || DEFAULTS.replicationFactor
  120. }
  121. />
  122. )}
  123. </div>
  124. );
  125. };
  126. export default Edit;