Edit.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import React from 'react';
  2. import {
  3. TopicFormDataRaw,
  4. TopicConfigByName,
  5. TopicFormData,
  6. } from 'redux/interfaces';
  7. import { useForm, FormProvider } from 'react-hook-form';
  8. import TopicForm from 'components/Topics/shared/Form/TopicForm';
  9. import { RouteParamsClusterTopic } from 'lib/paths';
  10. import { useNavigate } from 'react-router-dom';
  11. import { yupResolver } from '@hookform/resolvers/yup';
  12. import { topicFormValidationSchema } from 'lib/yupExtended';
  13. import useAppParams from 'lib/hooks/useAppParams';
  14. import topicParamsTransformer from 'components/Topics/Topic/Edit/topicParamsTransformer';
  15. import { MILLISECONDS_IN_WEEK } from 'lib/constants';
  16. import {
  17. useTopicConfig,
  18. useTopicDetails,
  19. useUpdateTopic,
  20. } from 'lib/hooks/api/topics';
  21. import DangerZone from 'components/Topics/Topic/Edit/DangerZone/DangerZone';
  22. import { ConfigSource } from 'generated-sources';
  23. export const TOPIC_EDIT_FORM_DEFAULT_PROPS = {
  24. partitions: 1,
  25. replicationFactor: 1,
  26. minInSyncReplicas: 1,
  27. cleanupPolicy: 'delete',
  28. retentionBytes: -1,
  29. retentionMs: MILLISECONDS_IN_WEEK,
  30. maxMessageBytes: 1000012,
  31. customParams: [],
  32. };
  33. const Edit: React.FC = () => {
  34. const { clusterName, topicName } = useAppParams<RouteParamsClusterTopic>();
  35. const { data: topic } = useTopicDetails({ clusterName, topicName });
  36. const { data: topicConfig } = useTopicConfig({ clusterName, topicName });
  37. const updateTopic = useUpdateTopic({ clusterName, topicName });
  38. const defaultValues = topicParamsTransformer(topic, topicConfig);
  39. const methods = useForm<TopicFormData>({
  40. defaultValues,
  41. resolver: yupResolver(topicFormValidationSchema),
  42. mode: 'onChange',
  43. });
  44. const navigate = useNavigate();
  45. const config: TopicConfigByName = {
  46. byName: {},
  47. };
  48. topicConfig?.forEach((param) => {
  49. config.byName[param.name] = param;
  50. });
  51. const onSubmit = async (data: TopicFormDataRaw) => {
  52. const filteredDirtyDefaultEntries = Object.entries(data).filter(
  53. ([key, val]) => {
  54. const isDirty =
  55. String(val) !==
  56. String(defaultValues[key as keyof typeof defaultValues]);
  57. const isDefaultConfig =
  58. config.byName[key]?.source === ConfigSource.DEFAULT_CONFIG;
  59. // if it is changed should be sent or if it was Dynamic
  60. return isDirty || !isDefaultConfig;
  61. }
  62. );
  63. const newData = Object.fromEntries(filteredDirtyDefaultEntries);
  64. await updateTopic.mutateAsync(newData);
  65. navigate('../');
  66. };
  67. return (
  68. <>
  69. <FormProvider {...methods}>
  70. <TopicForm
  71. config={config.byName}
  72. topicName={topicName}
  73. retentionBytes={defaultValues.retentionBytes}
  74. inSyncReplicas={Number(defaultValues.minInSyncReplicas)}
  75. isSubmitting={updateTopic.isLoading}
  76. cleanUpPolicy={topic?.cleanUpPolicy}
  77. isEditing
  78. onSubmit={methods.handleSubmit(onSubmit)}
  79. />
  80. </FormProvider>
  81. {topic && (
  82. <DangerZone
  83. defaultPartitions={defaultValues.partitions}
  84. defaultReplicationFactor={
  85. defaultValues.replicationFactor ||
  86. TOPIC_EDIT_FORM_DEFAULT_PROPS.replicationFactor
  87. }
  88. />
  89. )}
  90. </>
  91. );
  92. };
  93. export default Edit;