CustomParamField.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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)
  61. .sort()
  62. .map((opt) => (
  63. <option
  64. key={opt}
  65. value={opt}
  66. disabled={existingFields.includes(opt)}
  67. >
  68. {opt}
  69. </option>
  70. ))}
  71. </select>
  72. <p className="help is-danger">
  73. <ErrorMessage errors={errors} name={`customParams.${index}.name`} />
  74. </p>
  75. </div>
  76. </div>
  77. <div className="column">
  78. <label className="label">Value</label>
  79. <input
  80. className="input"
  81. placeholder="Value"
  82. {...register(`customParams.${index}.value` as const, {
  83. required: 'Value is required.',
  84. })}
  85. defaultValue={field.value}
  86. autoComplete="off"
  87. disabled={isDisabled}
  88. />
  89. <p className="help is-danger">
  90. <ErrorMessage errors={errors} name={`customParams.${index}.value`} />
  91. </p>
  92. </div>
  93. <div className="column is-narrow">
  94. <label className="label">&nbsp;</label>
  95. <CustomParamButton
  96. className="is-danger"
  97. type="fa-minus"
  98. onClick={() => remove(index)}
  99. />
  100. </div>
  101. </div>
  102. );
  103. };
  104. export default React.memo(CustomParamField);