New.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import React from 'react';
  2. import { NewSchemaSubjectRaw } from 'redux/interfaces';
  3. import { FormProvider, useForm, Controller } from 'react-hook-form';
  4. import { ErrorMessage } from '@hookform/error-message';
  5. import {
  6. ClusterNameRoute,
  7. clusterSchemaPath,
  8. clusterSchemasPath,
  9. } from 'lib/paths';
  10. import { SchemaType } from 'generated-sources';
  11. import { SCHEMA_NAME_VALIDATION_PATTERN } from 'lib/constants';
  12. import { useNavigate } from 'react-router-dom';
  13. import { InputLabel } from 'components/common/Input/InputLabel.styled';
  14. import Input from 'components/common/Input/Input';
  15. import { FormError } from 'components/common/Input/Input.styled';
  16. import Select, { SelectOption } from 'components/common/Select/Select';
  17. import { Button } from 'components/common/Button/Button';
  18. import { Textarea } from 'components/common/Textbox/Textarea.styled';
  19. import PageHeading from 'components/common/PageHeading/PageHeading';
  20. import { schemaAdded } from 'redux/reducers/schemas/schemasSlice';
  21. import { useAppDispatch } from 'lib/hooks/redux';
  22. import useAppParams from 'lib/hooks/useAppParams';
  23. import { showServerError } from 'lib/errorHandling';
  24. import { schemasApiClient } from 'lib/api';
  25. import * as S from './New.styled';
  26. const SchemaTypeOptions: Array<SelectOption> = [
  27. { value: SchemaType.AVRO, label: 'AVRO' },
  28. { value: SchemaType.JSON, label: 'JSON' },
  29. { value: SchemaType.PROTOBUF, label: 'PROTOBUF' },
  30. ];
  31. const New: React.FC = () => {
  32. const { clusterName } = useAppParams<ClusterNameRoute>();
  33. const navigate = useNavigate();
  34. const dispatch = useAppDispatch();
  35. const methods = useForm<NewSchemaSubjectRaw>({
  36. mode: 'onChange',
  37. defaultValues: {
  38. schemaType: SchemaType.AVRO,
  39. },
  40. });
  41. const {
  42. register,
  43. handleSubmit,
  44. control,
  45. formState: { isDirty, isSubmitting, errors, isValid },
  46. } = methods;
  47. const onSubmit = async ({
  48. subject,
  49. schema,
  50. schemaType,
  51. }: NewSchemaSubjectRaw) => {
  52. try {
  53. const resp = await schemasApiClient.createNewSchema({
  54. clusterName,
  55. newSchemaSubject: { subject, schema, schemaType },
  56. });
  57. dispatch(schemaAdded(resp));
  58. navigate(clusterSchemaPath(clusterName, subject));
  59. } catch (e) {
  60. showServerError(e as Response);
  61. }
  62. };
  63. return (
  64. <FormProvider {...methods}>
  65. <PageHeading
  66. text="Create"
  67. backText="Schema Registry"
  68. backTo={clusterSchemasPath(clusterName)}
  69. />
  70. <S.Form onSubmit={handleSubmit(onSubmit)}>
  71. <div>
  72. <InputLabel>Subject *</InputLabel>
  73. <Input
  74. inputSize="M"
  75. placeholder="Schema Name"
  76. name="subject"
  77. hookFormOptions={{
  78. required: 'Schema Name is required.',
  79. pattern: {
  80. value: SCHEMA_NAME_VALIDATION_PATTERN,
  81. message: 'Only alphanumeric, _, -, and . allowed',
  82. },
  83. }}
  84. autoComplete="off"
  85. disabled={isSubmitting}
  86. />
  87. <FormError>
  88. <ErrorMessage errors={errors} name="subject" />
  89. </FormError>
  90. </div>
  91. <div>
  92. <InputLabel>Schema *</InputLabel>
  93. <Textarea
  94. {...register('schema', {
  95. required: 'Schema is required.',
  96. })}
  97. disabled={isSubmitting}
  98. />
  99. <FormError>
  100. <ErrorMessage errors={errors} name="schema" />
  101. </FormError>
  102. </div>
  103. <div>
  104. <InputLabel>Schema Type *</InputLabel>
  105. <Controller
  106. control={control}
  107. rules={{ required: 'Schema Type is required.' }}
  108. name="schemaType"
  109. defaultValue={SchemaTypeOptions[0].value as SchemaType}
  110. render={({ field: { name, onChange, value } }) => (
  111. <Select
  112. selectSize="M"
  113. name={name}
  114. value={value}
  115. onChange={onChange}
  116. minWidth="100%"
  117. disabled={isSubmitting}
  118. options={SchemaTypeOptions}
  119. />
  120. )}
  121. />
  122. <FormError>
  123. <ErrorMessage errors={errors} name="schemaType" />
  124. </FormError>
  125. </div>
  126. <Button
  127. buttonSize="M"
  128. buttonType="primary"
  129. type="submit"
  130. disabled={!isValid || isSubmitting || !isDirty}
  131. >
  132. Submit
  133. </Button>
  134. </S.Form>
  135. </FormProvider>
  136. );
  137. };
  138. export default New;