Diff.tsx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import React from 'react';
  2. import { SchemaSubject } from 'generated-sources';
  3. import {
  4. clusterSchemaComparePath,
  5. clusterSchemasPath,
  6. ClusterSubjectParam,
  7. } from 'lib/paths';
  8. import PageLoader from 'components/common/PageLoader/PageLoader';
  9. import DiffViewer from 'components/common/DiffViewer/DiffViewer';
  10. import { useNavigate, useLocation } from 'react-router-dom';
  11. import {
  12. fetchSchemaVersions,
  13. SCHEMAS_VERSIONS_FETCH_ACTION,
  14. } from 'redux/reducers/schemas/schemasSlice';
  15. import { useForm, Controller } from 'react-hook-form';
  16. import Select from 'components/common/Select/Select';
  17. import { useAppDispatch } from 'lib/hooks/redux';
  18. import { resetLoaderById } from 'redux/reducers/loader/loaderSlice';
  19. import useAppParams from 'lib/hooks/useAppParams';
  20. import PageHeading from 'components/common/PageHeading/PageHeading';
  21. import * as S from './Diff.styled';
  22. import { BackButton } from './Diff.styled';
  23. export interface DiffProps {
  24. versions: SchemaSubject[];
  25. areVersionsFetched: boolean;
  26. }
  27. const Diff: React.FC<DiffProps> = ({ versions, areVersionsFetched }) => {
  28. const { clusterName, subject } = useAppParams<ClusterSubjectParam>();
  29. const navigate = useNavigate();
  30. const location = useLocation();
  31. const searchParams = React.useMemo(
  32. () => new URLSearchParams(location.search),
  33. [location]
  34. );
  35. const [leftVersion, setLeftVersion] = React.useState(
  36. searchParams.get('leftVersion') || ''
  37. );
  38. const [rightVersion, setRightVersion] = React.useState(
  39. searchParams.get('rightVersion') || ''
  40. );
  41. const dispatch = useAppDispatch();
  42. React.useEffect(() => {
  43. dispatch(fetchSchemaVersions({ clusterName, subject }));
  44. return () => {
  45. dispatch(resetLoaderById(SCHEMAS_VERSIONS_FETCH_ACTION));
  46. };
  47. }, [clusterName, subject, dispatch]);
  48. const getSchemaContent = (allVersions: SchemaSubject[], version: string) => {
  49. const selectedSchema =
  50. allVersions.find((s) => s.version === version)?.schema ||
  51. (allVersions.length ? allVersions[0].schema : '');
  52. return selectedSchema.trim().startsWith('{')
  53. ? JSON.stringify(JSON.parse(selectedSchema), null, '\t')
  54. : selectedSchema;
  55. };
  56. const getSchemaType = (allVersions: SchemaSubject[]) => {
  57. return allVersions[0].schemaType;
  58. };
  59. const methods = useForm({ mode: 'onChange' });
  60. const {
  61. formState: { isSubmitting },
  62. control,
  63. } = methods;
  64. return (
  65. <>
  66. <PageHeading
  67. text={`${subject} compare versions`}
  68. backText="Schema Registry"
  69. backTo={clusterSchemasPath(clusterName)}
  70. />
  71. <BackButton
  72. buttonType="secondary"
  73. buttonSize="S"
  74. onClick={() => navigate(-1)}
  75. >
  76. Back
  77. </BackButton>
  78. <S.Section>
  79. {areVersionsFetched ? (
  80. <S.DiffBox>
  81. <S.DiffTilesWrapper>
  82. <S.DiffTile>
  83. <S.DiffVersionsSelect>
  84. <Controller
  85. defaultValue={leftVersion}
  86. control={control}
  87. rules={{ required: true }}
  88. name="schemaType"
  89. render={({ field: { name } }) => (
  90. <Select
  91. id="left-select"
  92. name={name}
  93. value={
  94. leftVersion === '' ? versions[0].version : leftVersion
  95. }
  96. onChange={(event) => {
  97. navigate(
  98. clusterSchemaComparePath(clusterName, subject)
  99. );
  100. searchParams.set('leftVersion', event.toString());
  101. searchParams.set(
  102. 'rightVersion',
  103. rightVersion === ''
  104. ? versions[0].version
  105. : rightVersion
  106. );
  107. navigate({
  108. search: `?${searchParams.toString()}`,
  109. });
  110. setLeftVersion(event.toString());
  111. }}
  112. minWidth="100%"
  113. disabled={isSubmitting}
  114. options={versions.map((type) => ({
  115. value: type.version,
  116. label: `Version ${type.version}`,
  117. }))}
  118. />
  119. )}
  120. />
  121. </S.DiffVersionsSelect>
  122. </S.DiffTile>
  123. <S.DiffTile>
  124. <S.DiffVersionsSelect>
  125. <Controller
  126. defaultValue={rightVersion}
  127. control={control}
  128. rules={{ required: true }}
  129. name="schemaType"
  130. render={({ field: { name } }) => (
  131. <Select
  132. id="right-select"
  133. name={name}
  134. value={
  135. rightVersion === ''
  136. ? versions[0].version
  137. : rightVersion
  138. }
  139. onChange={(event) => {
  140. navigate(
  141. clusterSchemaComparePath(clusterName, subject)
  142. );
  143. searchParams.set(
  144. 'leftVersion',
  145. leftVersion === ''
  146. ? versions[0].version
  147. : leftVersion
  148. );
  149. searchParams.set('rightVersion', event.toString());
  150. navigate({
  151. search: `?${searchParams.toString()}`,
  152. });
  153. setRightVersion(event.toString());
  154. }}
  155. minWidth="100%"
  156. disabled={isSubmitting}
  157. options={versions.map((type) => ({
  158. value: type.version,
  159. label: `Version ${type.version}`,
  160. }))}
  161. />
  162. )}
  163. />
  164. </S.DiffVersionsSelect>
  165. </S.DiffTile>
  166. </S.DiffTilesWrapper>
  167. <S.DiffWrapper>
  168. <DiffViewer
  169. value={[
  170. getSchemaContent(versions, leftVersion),
  171. getSchemaContent(versions, rightVersion),
  172. ]}
  173. setOptions={{
  174. autoScrollEditorIntoView: true,
  175. }}
  176. isFixedHeight={false}
  177. schemaType={getSchemaType(versions)}
  178. />
  179. </S.DiffWrapper>
  180. </S.DiffBox>
  181. ) : (
  182. <PageLoader />
  183. )}
  184. </S.Section>
  185. </>
  186. );
  187. };
  188. export default Diff;