CustomParamField.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import React from 'react';
  2. import { ErrorMessage } from '@hookform/error-message';
  3. import { TOPIC_CUSTOM_PARAMS } from 'lib/constants';
  4. import { FieldArrayWithId, useFormContext } from 'react-hook-form';
  5. import { remove as _remove } from 'lodash';
  6. import { TopicFormData } from 'redux/interfaces';
  7. import CustomParamButton from './CustomParamButton';
  8. interface Props {
  9. isDisabled: boolean;
  10. index: number;
  11. existingFields: string[];
  12. field: FieldArrayWithId<TopicFormData, 'customParams', 'id'>;
  13. remove: (index?: number | number[] | undefined) => void;
  14. setExistingFields: React.Dispatch<React.SetStateAction<string[]>>;
  15. }
  16. const CustomParamField: React.FC<Props> = ({
  17. field,
  18. isDisabled,
  19. index,
  20. remove,
  21. existingFields,
  22. setExistingFields,
  23. }) => {
  24. const {
  25. register,
  26. formState: { errors },
  27. setValue,
  28. watch,
  29. } = useFormContext<TopicFormData>();
  30. const nameValue = watch(`customParams.${index}.name`);
  31. let prevName = '';
  32. React.useEffect(() => {
  33. prevName = nameValue;
  34. }, []);
  35. React.useEffect(() => {
  36. if (nameValue !== prevName) {
  37. let newExistingFields = [...existingFields];
  38. if (prevName) {
  39. newExistingFields = _remove(newExistingFields, (el) => el === prevName);
  40. }
  41. prevName = nameValue;
  42. newExistingFields.push(nameValue);
  43. setExistingFields(newExistingFields);
  44. setValue(`customParams.${index}.value`, TOPIC_CUSTOM_PARAMS[nameValue]);
  45. }
  46. }, [nameValue]);
  47. return (
  48. <div className="columns is-centered">
  49. <div className="column">
  50. <label className="label">Custom Parameter</label>
  51. <div className="select is-block">
  52. <select
  53. {...register(`customParams.${index}.name` as const, {
  54. required: 'Custom Parameter is required.',
  55. })}
  56. disabled={isDisabled}
  57. defaultValue={field.name}
  58. >
  59. <option value="">Select</option>
  60. {Object.keys(TOPIC_CUSTOM_PARAMS).map((opt) => (
  61. <option
  62. key={opt}
  63. value={opt}
  64. disabled={existingFields.includes(opt)}
  65. >
  66. {opt}
  67. </option>
  68. ))}
  69. </select>
  70. <p className="help is-danger">
  71. <ErrorMessage errors={errors} name={`customParams.${index}.name`} />
  72. </p>
  73. </div>
  74. </div>
  75. <div className="column">
  76. <label className="label">Value</label>
  77. <input
  78. className="input"
  79. placeholder="Value"
  80. {...register(`customParams.${index}.value` as const, {
  81. required: 'Value is required.',
  82. })}
  83. defaultValue={field.value}
  84. autoComplete="off"
  85. disabled={isDisabled}
  86. />
  87. <p className="help is-danger">
  88. <ErrorMessage errors={errors} name={`customParams.${index}.value`} />
  89. </p>
  90. </div>
  91. <div className="column is-narrow">
  92. <label className="label">&nbsp;</label>
  93. <CustomParamButton
  94. className="is-danger"
  95. type="fa-minus"
  96. onClick={() => remove(index)}
  97. />
  98. </div>
  99. </div>
  100. );
  101. };
  102. export default React.memo(CustomParamField);