Diff.tsx 6.1 KB

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