[CHORE] Get rid of react-json-tree (#387)

This commit is contained in:
Oleg Shur 2021-04-23 13:50:13 +03:00 committed by GitHub
parent f935083b09
commit 993db2fc00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 425 additions and 511 deletions

View file

@ -21,7 +21,6 @@
"react-datepicker": "^3.7.0", "react-datepicker": "^3.7.0",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-hook-form": "^6.15.5", "react-hook-form": "^6.15.5",
"react-json-tree": "^0.15.0",
"react-multi-select-component": "^4.0.0", "react-multi-select-component": "^4.0.0",
"react-redux": "^7.2.2", "react-redux": "^7.2.2",
"react-router": "^5.2.0", "react-router": "^5.2.0",

View file

@ -54,30 +54,28 @@ const Details: React.FC<Props> = ({
{isFetched ? ( {isFetched ? (
<div className="box"> <div className="box">
<div className="table-container"> <table className="table is-striped is-fullwidth">
<table className="table is-striped is-fullwidth"> <thead>
<thead> <tr>
<tr> <th>Consumer ID</th>
<th>Consumer ID</th> <th>Host</th>
<th>Host</th> <th>Topic</th>
<th>Topic</th> <th>Partition</th>
<th>Partition</th> <th>Messages behind</th>
<th>Messages behind</th> <th>Current offset</th>
<th>Current offset</th> <th>End offset</th>
<th>End offset</th> </tr>
</tr> </thead>
</thead> <tbody>
<tbody> {items.map((consumer) => (
{items.map((consumer) => ( <ListItem
<ListItem key={consumer.consumerId}
key={consumer.consumerId} clusterName={clusterName}
clusterName={clusterName} consumer={consumer}
consumer={consumer} />
/> ))}
))} </tbody>
</tbody> </table>
</table>
</div>
</div> </div>
) : ( ) : (
<PageLoader /> <PageLoader />

View file

@ -37,31 +37,29 @@ const List: React.FC<Props> = ({ consumerGroups }) => {
/> />
</div> </div>
</div> </div>
<div className="table-container"> <table className="table is-striped is-fullwidth is-hoverable">
<table className="table is-striped is-fullwidth is-hoverable"> <thead>
<thead> <tr>
<tr> <th>Consumer group ID</th>
<th>Consumer group ID</th> <th>Num of consumers</th>
<th>Num of consumers</th> <th>Num of topics</th>
<th>Num of topics</th> </tr>
</tr> </thead>
</thead> <tbody>
<tbody> {consumerGroups
{consumerGroups .filter(
.filter( (consumerGroup) =>
(consumerGroup) => !searchText ||
!searchText || consumerGroup?.consumerGroupId?.indexOf(searchText) >= 0
consumerGroup?.consumerGroupId?.indexOf(searchText) >= 0 )
) .map((consumerGroup) => (
.map((consumerGroup) => ( <ListItem
<ListItem key={consumerGroup.consumerGroupId}
key={consumerGroup.consumerGroupId} consumerGroup={consumerGroup}
consumerGroup={consumerGroup} />
/> ))}
))} </tbody>
</tbody> </table>
</table>
</div>
</div> </div>
) : ( ) : (
'No active consumer groups' 'No active consumer groups'

View file

@ -112,22 +112,20 @@ const Details: React.FC<DetailsProps> = ({
<LatestVersionItem schema={schema} /> <LatestVersionItem schema={schema} />
</div> </div>
<div className="box"> <div className="box">
<div className="table-container"> <table className="table is-fullwidth">
<table className="table is-striped is-fullwidth"> <thead>
<thead> <tr>
<tr> <th>Version</th>
<th>Version</th> <th>ID</th>
<th>ID</th> <th>Schema</th>
<th>Schema</th> </tr>
</tr> </thead>
</thead> <tbody>
<tbody> {versions.map((version) => (
{versions.map((version) => ( <SchemaVersion key={version.id} version={version} />
<SchemaVersion key={version.id} version={version} /> ))}
))} </tbody>
</tbody> </table>
</table>
</div>
</div> </div>
</> </>
) : ( ) : (

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { SchemaSubject } from 'generated-sources'; import { SchemaSubject } from 'generated-sources';
import JSONViewer from 'components/common/JSONViewer/JSONViewer'; import JSONEditor from 'components/common/JSONEditor/JSONEditor';
interface LatestVersionProps { interface LatestVersionProps {
schema: SchemaSubject; schema: SchemaSubject;
@ -12,29 +12,32 @@ const LatestVersionItem: React.FC<LatestVersionProps> = ({
<div className="tile is-ancestor mt-1"> <div className="tile is-ancestor mt-1">
<div className="tile is-4 is-parent"> <div className="tile is-4 is-parent">
<div className="tile is-child"> <div className="tile is-child">
<div className="table-container"> <table className="table is-fullwidth">
<table className="table is-fullwidth"> <tbody>
<tbody> <tr>
<tr> <td>ID</td>
<td>ID</td> <td>{id}</td>
<td>{id}</td> </tr>
</tr> <tr>
<tr> <td>Subject</td>
<td>Subject</td> <td>{subject}</td>
<td>{subject}</td> </tr>
</tr> <tr>
<tr> <td>Compatibility</td>
<td>Compatibility</td> <td>{compatibilityLevel}</td>
<td>{compatibilityLevel}</td> </tr>
</tr> </tbody>
</tbody> </table>
</table>
</div>
</div> </div>
</div> </div>
<div className="tile is-parent"> <div className="tile is-parent">
<div className="tile is-child box py-1"> <div className="tile is-child box">
<JSONViewer data={JSON.parse(schema)} /> <JSONEditor
name="schema"
value={JSON.stringify(JSON.parse(schema), null, '\t')}
showGutter={false}
readOnly
/>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { SchemaSubject } from 'generated-sources'; import { SchemaSubject } from 'generated-sources';
import JSONViewer from 'components/common/JSONViewer/JSONViewer'; import JSONEditor from 'components/common/JSONEditor/JSONEditor';
interface SchemaVersionProps { interface SchemaVersionProps {
version: SchemaSubject; version: SchemaSubject;
@ -13,8 +13,13 @@ const SchemaVersion: React.FC<SchemaVersionProps> = ({
<tr> <tr>
<td>{version}</td> <td>{version}</td>
<td>{id}</td> <td>{id}</td>
<td className="py-0"> <td>
<JSONViewer data={JSON.parse(schema)} /> <JSONEditor
name="schema"
value={JSON.stringify(JSON.parse(schema), null, '\t')}
showGutter={false}
readOnly
/>
</td> </td>
</tr> </tr>
); );

View file

@ -10,7 +10,7 @@ describe('LatestVersionItem', () => {
expect(wrapper.find('table').length).toEqual(1); expect(wrapper.find('table').length).toEqual(1);
expect(wrapper.find('td').at(1).text()).toEqual('1'); expect(wrapper.find('td').at(1).text()).toEqual('1');
expect(wrapper.exists('JSONViewer')).toBeTruthy(); expect(wrapper.exists('JSONEditor')).toBeTruthy();
}); });
it('matches snapshot', () => { it('matches snapshot', () => {

View file

@ -9,7 +9,7 @@ describe('SchemaVersion', () => {
const wrapper = shallow(<SchemaVersion version={versions[0]} />); const wrapper = shallow(<SchemaVersion version={versions[0]} />);
expect(wrapper.find('td').length).toEqual(3); expect(wrapper.find('td').length).toEqual(3);
expect(wrapper.exists('JSONViewer')).toBeTruthy(); expect(wrapper.exists('JSONEditor')).toBeTruthy();
}); });
it('matches snapshot', () => { it('matches snapshot', () => {

View file

@ -94,28 +94,24 @@ exports[`Details View Initial state matches snapshot 1`] = `
<div <div
className="box" className="box"
> >
<div <table
className="table-container" className="table is-fullwidth"
> >
<table <thead>
className="table is-striped is-fullwidth" <tr>
> <th>
<thead> Version
<tr> </th>
<th> <th>
Version ID
</th> </th>
<th> <th>
ID Schema
</th> </th>
<th> </tr>
Schema </thead>
</th> <tbody />
</tr> </table>
</thead>
<tbody />
</table>
</div>
</div> </div>
</div> </div>
`; `;
@ -238,55 +234,51 @@ exports[`Details View when page with schema versions loaded when schema has vers
<div <div
className="box" className="box"
> >
<div <table
className="table-container" className="table is-fullwidth"
> >
<table <thead>
className="table is-striped is-fullwidth" <tr>
> <th>
<thead> Version
<tr> </th>
<th> <th>
Version ID
</th> </th>
<th> <th>
ID Schema
</th> </th>
<th> </tr>
Schema </thead>
</th> <tbody>
</tr> <SchemaVersion
</thead> key="1"
<tbody> version={
<SchemaVersion Object {
key="1" "compatibilityLevel": "BACKWARD",
version={ "id": 1,
Object { "schema": "{\\"type\\":\\"record\\",\\"name\\":\\"MyRecord1\\",\\"namespace\\":\\"com.mycompany\\",\\"fields\\":[{\\"name\\":\\"id\\",\\"type\\":\\"long\\"}]}",
"compatibilityLevel": "BACKWARD", "schemaType": "JSON",
"id": 1, "subject": "test",
"schema": "{\\"type\\":\\"record\\",\\"name\\":\\"MyRecord1\\",\\"namespace\\":\\"com.mycompany\\",\\"fields\\":[{\\"name\\":\\"id\\",\\"type\\":\\"long\\"}]}", "version": "1",
"schemaType": "JSON",
"subject": "test",
"version": "1",
}
} }
/> }
<SchemaVersion />
key="2" <SchemaVersion
version={ key="2"
Object { version={
"compatibilityLevel": "BACKWARD", Object {
"id": 2, "compatibilityLevel": "BACKWARD",
"schema": "{\\"type\\":\\"record\\",\\"name\\":\\"MyRecord2\\",\\"namespace\\":\\"com.mycompany\\",\\"fields\\":[{\\"name\\":\\"id\\",\\"type\\":\\"long\\"}]}", "id": 2,
"schemaType": "JSON", "schema": "{\\"type\\":\\"record\\",\\"name\\":\\"MyRecord2\\",\\"namespace\\":\\"com.mycompany\\",\\"fields\\":[{\\"name\\":\\"id\\",\\"type\\":\\"long\\"}]}",
"subject": "test", "schemaType": "JSON",
"version": "2", "subject": "test",
} "version": "2",
} }
/> }
</tbody> />
</table> </tbody>
</div> </table>
</div> </div>
</div> </div>
`; `;
@ -385,28 +377,24 @@ exports[`Details View when page with schema versions loaded when versions are em
<div <div
className="box" className="box"
> >
<div <table
className="table-container" className="table is-fullwidth"
> >
<table <thead>
className="table is-striped is-fullwidth" <tr>
> <th>
<thead> Version
<tr> </th>
<th> <th>
Version ID
</th> </th>
<th> <th>
ID Schema
</th> </th>
<th> </tr>
Schema </thead>
</th> <tbody />
</tr> </table>
</thead>
<tbody />
</table>
</div>
</div> </div>
</div> </div>
`; `;

View file

@ -10,62 +10,59 @@ exports[`LatestVersionItem matches snapshot 1`] = `
<div <div
className="tile is-child" className="tile is-child"
> >
<div <table
className="table-container" className="table is-fullwidth"
> >
<table <tbody>
className="table is-fullwidth" <tr>
> <td>
<tbody> ID
<tr> </td>
<td> <td>
ID 1
</td> </td>
<td> </tr>
1 <tr>
</td> <td>
</tr> Subject
<tr> </td>
<td> <td>
Subject test
</td> </td>
<td> </tr>
test <tr>
</td> <td>
</tr> Compatibility
<tr> </td>
<td> <td>
Compatibility BACKWARD
</td> </td>
<td> </tr>
BACKWARD </tbody>
</td> </table>
</tr>
</tbody>
</table>
</div>
</div> </div>
</div> </div>
<div <div
className="tile is-parent" className="tile is-parent"
> >
<div <div
className="tile is-child box py-1" className="tile is-child box"
> >
<JSONViewer <JSONEditor
data={ name="schema"
Object { readOnly={true}
"fields": Array [ showGutter={false}
Object { value="{
"name": "id", \\"type\\": \\"record\\",
"type": "long", \\"name\\": \\"MyRecord1\\",
}, \\"namespace\\": \\"com.mycompany\\",
], \\"fields\\": [
"name": "MyRecord1", {
"namespace": "com.mycompany", \\"name\\": \\"id\\",
"type": "record", \\"type\\": \\"long\\"
} }
} ]
}"
/> />
</div> </div>
</div> </div>

View file

@ -8,23 +8,22 @@ exports[`SchemaVersion matches snapshot 1`] = `
<td> <td>
1 1
</td> </td>
<td <td>
className="py-0" <JSONEditor
> name="schema"
<JSONViewer readOnly={true}
data={ showGutter={false}
Object { value="{
"fields": Array [ \\"type\\": \\"record\\",
Object { \\"name\\": \\"MyRecord1\\",
"name": "id", \\"namespace\\": \\"com.mycompany\\",
"type": "long", \\"fields\\": [
}, {
], \\"name\\": \\"id\\",
"name": "MyRecord1", \\"type\\": \\"long\\"
"namespace": "com.mycompany", }
"type": "record", ]
} }"
}
/> />
</td> </td>
</tr> </tr>

View file

@ -1,16 +1,16 @@
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb'; import React from 'react';
import { useHistory } from 'react-router';
import { useForm, Controller } from 'react-hook-form';
import { import {
CompatibilityLevelCompatibilityEnum, CompatibilityLevelCompatibilityEnum,
SchemaSubject, SchemaSubject,
SchemaType, SchemaType,
} from 'generated-sources'; } from 'generated-sources';
import { clusterSchemaPath, clusterSchemasPath } from 'lib/paths'; import { clusterSchemaPath, clusterSchemasPath } from 'lib/paths';
import React from 'react';
import { ClusterName, NewSchemaSubjectRaw, SchemaName } from 'redux/interfaces'; import { ClusterName, NewSchemaSubjectRaw, SchemaName } from 'redux/interfaces';
import PageLoader from 'components/common/PageLoader/PageLoader'; import PageLoader from 'components/common/PageLoader/PageLoader';
import { useHistory } from 'react-router';
import JSONEditor from 'components/common/JSONEditor/JSONEditor'; import JSONEditor from 'components/common/JSONEditor/JSONEditor';
import { useForm } from 'react-hook-form'; import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
export interface EditProps { export interface EditProps {
subject: SchemaName; subject: SchemaName;
@ -143,17 +143,24 @@ const Edit = ({
<div className="column is-one-half"> <div className="column is-one-half">
<h4 className="title is-5 mb-2">Latest Schema</h4> <h4 className="title is-5 mb-2">Latest Schema</h4>
<JSONEditor <JSONEditor
readonly readOnly
value={getFormattedSchema()} value={getFormattedSchema()}
name="latestSchema" name="latestSchema"
highlightActiveLine={false}
/> />
</div> </div>
<div className="column is-one-half"> <div className="column is-one-half">
<h4 className="title is-5 mb-2">New Schema</h4> <h4 className="title is-5 mb-2">New Schema</h4>
<JSONEditor <Controller
control={control} control={control}
value={getFormattedSchema()}
name="newSchema" name="newSchema"
render={({ name, onChange }) => (
<JSONEditor
defaultValue={getFormattedSchema()}
name={name}
onChange={onChange}
/>
)}
/> />
</div> </div>
</div> </div>

View file

@ -54,7 +54,10 @@ describe('Edit Component', () => {
expect(component).toMatchSnapshot(); expect(component).toMatchSnapshot();
}); });
it('shows editor', () => { it('shows editor', () => {
expect(component.find('JSONEditor').length).toEqual(2); expect(component.find('JSONEditor[name="latestSchema"]').length).toEqual(
1
);
expect(component.find('Controller[name="newSchema"]').length).toEqual(1);
expect(component.find('button').exists()).toBeTruthy(); expect(component.find('button').exists()).toBeTruthy();
}); });
it('does not fetch them', () => { it('does not fetch them', () => {

View file

@ -143,8 +143,9 @@ exports[`Edit Component when schemas are fetched matches the snapshot 1`] = `
Latest Schema Latest Schema
</h4> </h4>
<JSONEditor <JSONEditor
highlightActiveLine={false}
name="latestSchema" name="latestSchema"
readonly={true} readOnly={true}
value="{ value="{
\\"schema\\": \\"schema\\" \\"schema\\": \\"schema\\"
}" }"
@ -158,7 +159,7 @@ exports[`Edit Component when schemas are fetched matches the snapshot 1`] = `
> >
New Schema New Schema
</h4> </h4>
<JSONEditor <Controller
control={ control={
Object { Object {
"defaultValuesRef": Object { "defaultValuesRef": Object {
@ -261,9 +262,7 @@ exports[`Edit Component when schemas are fetched matches the snapshot 1`] = `
} }
} }
name="newSchema" name="newSchema"
value="{ render={[Function]}
\\"schema\\": \\"schema\\"
}"
/> />
</div> </div>
</div> </div>

View file

@ -49,27 +49,25 @@ const List: React.FC<ListProps> = ({
<PageLoader /> <PageLoader />
) : ( ) : (
<div className="box"> <div className="box">
<div className="table-container"> <table className="table is-striped is-fullwidth">
<table className="table is-striped is-fullwidth"> <thead>
<thead> <tr>
<th>Schema Name</th>
<th>Version</th>
<th>Compatibility</th>
</tr>
</thead>
<tbody>
{schemas.length === 0 && (
<tr> <tr>
<th>Schema Name</th> <td colSpan={10}>No schemas found</td>
<th>Version</th>
<th>Compatibility</th>
</tr> </tr>
</thead> )}
<tbody> {schemas.map((subject) => (
{schemas.length === 0 && ( <ListItem key={subject.id} subject={subject} />
<tr> ))}
<td colSpan={10}>No schemas found</td> </tbody>
</tr> </table>
)}
{schemas.map((subject) => (
<ListItem key={subject.id} subject={subject} />
))}
</tbody>
</table>
</div>
</div> </div>
)} )}
</div> </div>

View file

@ -88,36 +88,34 @@ const List: React.FC<Props> = ({
<PageLoader /> <PageLoader />
) : ( ) : (
<div className="box"> <div className="box">
<div className="table-container"> <table className="table is-fullwidth">
<table className="table is-fullwidth"> <thead>
<thead> <tr>
<th>Topic Name</th>
<th>Total Partitions</th>
<th>Out of sync replicas</th>
<th>Type</th>
<th> </th>
</tr>
</thead>
<tbody>
{items.map((topic) => (
<ListItem
clusterName={clusterName}
key={topic.name}
topic={topic}
deleteTopic={deleteTopic}
clearTopicMessages={clearTopicMessages}
/>
))}
{items.length === 0 && (
<tr> <tr>
<th>Topic Name</th> <td colSpan={10}>No topics found</td>
<th>Total Partitions</th>
<th>Out of sync replicas</th>
<th>Type</th>
<th> </th>
</tr> </tr>
</thead> )}
<tbody> </tbody>
{items.map((topic) => ( </table>
<ListItem <Pagination totalPages={totalPages} />
clusterName={clusterName}
key={topic.name}
topic={topic}
deleteTopic={deleteTopic}
clearTopicMessages={clearTopicMessages}
/>
))}
{items.length === 0 && (
<tr>
<td colSpan={10}>No topics found</td>
</tr>
)}
</tbody>
</table>
<Pagination totalPages={totalPages} />
</div>
</div> </div>
)} )}
</div> </div>

View file

@ -1,10 +1,9 @@
import React from 'react'; import React from 'react';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { TopicMessage } from 'generated-sources'; import { TopicMessage } from 'generated-sources';
import JSONViewer from 'components/common/JSONViewer/JSONViewer';
import { isObject } from 'lodash';
import Dropdown from 'components/common/Dropdown/Dropdown'; import Dropdown from 'components/common/Dropdown/Dropdown';
import DropdownItem from 'components/common/Dropdown/DropdownItem'; import DropdownItem from 'components/common/Dropdown/DropdownItem';
import JSONEditor from 'components/common/JSONEditor/JSONEditor';
import useDataSaver from 'lib/hooks/useDataSaver'; import useDataSaver from 'lib/hooks/useDataSaver';
export interface MessageItemProp { export interface MessageItemProp {
@ -24,18 +23,19 @@ const MessageItem: React.FC<MessageItemProp> = ({
'topic-message', 'topic-message',
(content as Record<string, string>) || '' (content as Record<string, string>) || ''
); );
return ( return (
<tr> <tr>
<td style={{ width: 200 }}>{format(timestamp, 'yyyy-MM-dd HH:mm:ss')}</td> <td style={{ width: 200 }}>{format(timestamp, 'yyyy-MM-dd HH:mm:ss')}</td>
<td style={{ width: 150 }}>{offset}</td> <td style={{ width: 150 }}>{offset}</td>
<td style={{ width: 100 }}>{partition}</td> <td style={{ width: 100 }}>{partition}</td>
<td style={{ wordBreak: 'break-word' }}> <td style={{ wordBreak: 'break-word' }}>
{isObject(content) ? ( <JSONEditor
<JSONViewer data={content as Record<string, string>} /> readOnly
) : ( value={JSON.stringify(content, null, '\t')}
content name="latestSchema"
)} highlightActiveLine={false}
height="300px"
/>
</td> </td>
<td className="has-text-right"> <td className="has-text-right">
<Dropdown <Dropdown

View file

@ -16,32 +16,30 @@ const MessagesTable: React.FC<MessagesTableProp> = ({ messages, onNext }) => {
return ( return (
<> <>
<div className="table-container"> <table className="table is-fullwidth">
<table className="table is-fullwidth"> <thead>
<thead> <tr>
<tr> <th>Timestamp</th>
<th>Timestamp</th> <th>Offset</th>
<th>Offset</th> <th>Partition</th>
<th>Partition</th> <th>Content</th>
<th>Content</th> <th> </th>
<th> </th> </tr>
</tr> </thead>
</thead> <tbody>
<tbody> {messages.map(
{messages.map( ({ partition, offset, timestamp, content }: TopicMessage) => (
({ partition, offset, timestamp, content }: TopicMessage) => ( <MessageItem
<MessageItem key={`message-${timestamp.getTime()}-${offset}`}
key={`message-${timestamp.getTime()}-${offset}`} partition={partition}
partition={partition} offset={offset}
offset={offset} timestamp={timestamp}
timestamp={timestamp} content={content}
content={content} />
/> )
) )}
)} </tbody>
</tbody> </table>
</table>
</div>
<div className="columns"> <div className="columns">
<div className="column is-full"> <div className="column is-full">
<CustomParamButton <CustomParamButton

View file

@ -10,12 +10,12 @@ jest.mock('date-fns', () => ({
describe('MessageItem', () => { describe('MessageItem', () => {
describe('when content is defined', () => { describe('when content is defined', () => {
it('renders table row with JSONTree', () => { it('renders table row with JSONEditor', () => {
const wrapper = shallow(<MessageItem {...messages[0]} />); const wrapper = shallow(<MessageItem {...messages[0]} />);
expect(wrapper.find('tr').length).toEqual(1); expect(wrapper.find('tr').length).toEqual(1);
expect(wrapper.find('td').length).toEqual(5); expect(wrapper.find('td').length).toEqual(5);
expect(wrapper.find('JSONViewer').length).toEqual(1); expect(wrapper.find('JSONEditor').length).toEqual(1);
}); });
it('matches snapshot', () => { it('matches snapshot', () => {
@ -24,14 +24,6 @@ describe('MessageItem', () => {
}); });
describe('when content is undefined', () => { describe('when content is undefined', () => {
it('renders table row without JSONTree', () => {
const wrapper = shallow(<MessageItem {...messages[1]} />);
expect(wrapper.find('tr').length).toEqual(1);
expect(wrapper.find('td').length).toEqual(5);
expect(wrapper.find('JSONViewer').length).toEqual(0);
});
it('matches snapshot', () => { it('matches snapshot', () => {
expect(shallow(<MessageItem {...messages[1]} />)).toMatchSnapshot(); expect(shallow(<MessageItem {...messages[1]} />)).toMatchSnapshot();
}); });

View file

@ -65,8 +65,8 @@ describe('Messages', () => {
it('renders table', () => { it('renders table', () => {
expect(messagesWrapper.exists('.table.is-fullwidth')).toBeTruthy(); expect(messagesWrapper.exists('.table.is-fullwidth')).toBeTruthy();
}); });
it('renders JSONTree', () => { it('renders JSONEditor', () => {
expect(messagesWrapper.find('JSONTree').length).toEqual(1); expect(messagesWrapper.find('JSONEditor').length).toEqual(1);
}); });
it('parses message content correctly', () => { it('parses message content correctly', () => {
const messages = [ const messages = [

View file

@ -16,7 +16,7 @@ describe('MessagesTable', () => {
); );
describe('when topic is empty', () => { describe('when topic is empty', () => {
it('renders table row with JSONTree', () => { it('renders table row with JSONEditor', () => {
const wrapper = shallow(setupWrapper()); const wrapper = shallow(setupWrapper());
expect(wrapper.exists('table')).toBeFalsy(); expect(wrapper.exists('table')).toBeFalsy();
expect(wrapper.exists('CustomParamButton')).toBeFalsy(); expect(wrapper.exists('CustomParamButton')).toBeFalsy();
@ -32,7 +32,7 @@ describe('MessagesTable', () => {
const onNext = jest.fn(); const onNext = jest.fn();
const wrapper = shallow(setupWrapper({ messages, onNext })); const wrapper = shallow(setupWrapper({ messages, onNext }));
it('renders table row without JSONTree', () => { it('renders table row without JSONEditor', () => {
expect(wrapper.exists('table')).toBeTruthy(); expect(wrapper.exists('table')).toBeTruthy();
expect(wrapper.exists('CustomParamButton')).toBeTruthy(); expect(wrapper.exists('CustomParamButton')).toBeTruthy();
expect(wrapper.find('MessageItem').length).toEqual(2); expect(wrapper.find('MessageItem').length).toEqual(2);

View file

@ -36,13 +36,15 @@ exports[`MessageItem when content is defined matches snapshot 1`] = `
} }
} }
> >
<JSONViewer <JSONEditor
data={ height="300px"
Object { highlightActiveLine={false}
"foo": "bar", name="latestSchema"
"key": "val", readOnly={true}
} value="{
} \\"foo\\": \\"bar\\",
\\"key\\": \\"val\\"
}"
/> />
</td> </td>
<td <td
@ -110,7 +112,14 @@ exports[`MessageItem when content is undefined matches snapshot 1`] = `
"wordBreak": "break-word", "wordBreak": "break-word",
} }
} }
/> >
<JSONEditor
height="300px"
highlightActiveLine={false}
name="latestSchema"
readOnly={true}
/>
</td>
<td <td
className="has-text-right" className="has-text-right"
> >

View file

@ -2,53 +2,49 @@
exports[`MessagesTable when topic contains messages matches snapshot 1`] = ` exports[`MessagesTable when topic contains messages matches snapshot 1`] = `
<Fragment> <Fragment>
<div <table
className="table-container" className="table is-fullwidth"
> >
<table <thead>
className="table is-fullwidth" <tr>
> <th>
<thead> Timestamp
<tr> </th>
<th> <th>
Timestamp Offset
</th> </th>
<th> <th>
Offset Partition
</th> </th>
<th> <th>
Partition Content
</th> </th>
<th> <th>
Content
</th>
<th>
</th> </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<MessageItem <MessageItem
content={ content={
Object { Object {
"foo": "bar", "foo": "bar",
"key": "val", "key": "val",
}
} }
key="message-802310400000-2" }
offset={2} key="message-802310400000-2"
partition={1} offset={2}
timestamp={1995-06-05T00:00:00.000Z} partition={1}
/> timestamp={1995-06-05T00:00:00.000Z}
<MessageItem />
key="message-1596585600000-20" <MessageItem
offset={20} key="message-1596585600000-20"
partition={2} offset={20}
timestamp={2020-08-05T00:00:00.000Z} partition={2}
/> timestamp={2020-08-05T00:00:00.000Z}
</tbody> />
</table> </tbody>
</div> </table>
<div <div
className="columns" className="columns"
> >

View file

@ -47,22 +47,20 @@ const Settings: React.FC<Props> = ({
return ( return (
<div className="box"> <div className="box">
<div className="table-container"> <table className="table is-striped is-fullwidth">
<table className="table is-striped is-fullwidth"> <thead>
<thead> <tr>
<tr> <th>Key</th>
<th>Key</th> <th>Value</th>
<th>Value</th> <th>Default Value</th>
<th>Default Value</th> </tr>
</tr> </thead>
</thead> <tbody>
<tbody> {config.map((item) => (
{config.map((item) => ( <ConfigListItem key={item.name} config={item} />
<ConfigListItem key={item.name} config={item} /> ))}
))} </tbody>
</tbody> </table>
</table>
</div>
</div> </div>
); );
}; };

View file

@ -1,56 +1,18 @@
import AceEditor from 'react-ace'; /* eslint-disable react/jsx-props-no-spreading */
import AceEditor, { IAceEditorProps } from 'react-ace';
import 'ace-builds/src-noconflict/mode-json5'; import 'ace-builds/src-noconflict/mode-json5';
import 'ace-builds/src-noconflict/theme-dawn'; import 'ace-builds/src-noconflict/theme-textmate';
import React from 'react'; import React from 'react';
import { Control, Controller } from 'react-hook-form';
interface JSONEditorProps { const JSONEditor: React.FC<IAceEditorProps> = (props) => (
readonly?: boolean; <AceEditor
onChange?: (e: string) => void; mode="json5"
value: string; theme="textmate"
name: string; tabSize={2}
control?: Control; width="100%"
} wrapEnabled
{...props}
const JSONEditor: React.FC<JSONEditorProps> = ({ />
readonly, );
onChange,
value,
name,
control,
}) => {
if (control) {
return (
<Controller
control={control}
name={name}
as={
<AceEditor
defaultValue={value}
mode="json5"
theme="dawn"
name={name}
tabSize={2}
width="100%"
wrapEnabled
/>
}
/>
);
}
return (
<AceEditor
mode="json5"
theme="dawn"
name={name}
value={value}
tabSize={2}
width="100%"
readOnly={readonly}
onChange={onChange}
wrapEnabled
/>
);
};
export default JSONEditor; export default JSONEditor;

View file

@ -35,7 +35,7 @@ exports[`JSONEditor component matches the snapshot 1`] = `
showPrintMargin={true} showPrintMargin={true}
style={Object {}} style={Object {}}
tabSize={2} tabSize={2}
theme="dawn" theme="textmate"
value="{}" value="{}"
width="100%" width="100%"
wrapEnabled={true} wrapEnabled={true}

View file

@ -1,13 +0,0 @@
import React from 'react';
import JSONTree from 'react-json-tree';
import theme from 'components/common/JSONViewer/themes/google';
interface JSONViewerProps {
data: Record<string, string>;
}
const JSONViewer: React.FC<JSONViewerProps> = ({ data }) => (
<JSONTree data={data} theme={theme} shouldExpandNode={() => true} hideRoot />
);
export default JSONViewer;

View file

@ -1,20 +0,0 @@
export default {
scheme: 'google',
author: 'seth wright (http://sethawright.com)',
base00: '#1d1f21',
base01: '#282a2e',
base02: '#373b41',
base03: '#969896',
base04: '#b4b7b4',
base05: '#c5c8c6',
base06: '#e0e0e0',
base07: '#ffffff',
base08: '#CC342B',
base09: '#F96A38',
base0A: '#FBA922',
base0B: '#198844',
base0C: '#3971ED',
base0D: '#3971ED',
base0E: '#A36AC7',
base0F: '#3971ED',
};

View file

@ -1,3 +1,4 @@
import { orderBy } from 'lodash';
import { import {
createSchemaAction, createSchemaAction,
fetchSchemasByClusterNameAction, fetchSchemasByClusterNameAction,
@ -65,9 +66,9 @@ describe('Schemas selectors', () => {
); );
}); });
it('returns sorted versions of schema', () => { it('returns ordered versions of schema', () => {
expect(selectors.getSortedSchemaVersions(store.getState())).toEqual( expect(selectors.getSortedSchemaVersions(store.getState())).toEqual(
schemaVersionsPayload orderBy(schemaVersionsPayload, 'id', 'desc')
); );
}); });
}); });

View file

@ -1,7 +1,7 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { orderBy } from 'lodash';
import { RootState, SchemasState } from 'redux/interfaces'; import { RootState, SchemasState } from 'redux/interfaces';
import { createFetchingSelector } from 'redux/reducers/loader/selectors'; import { createFetchingSelector } from 'redux/reducers/loader/selectors';
import { sortBy } from 'lodash';
const schemasState = ({ schemas }: RootState): SchemasState => schemas; const schemasState = ({ schemas }: RootState): SchemasState => schemas;
@ -56,5 +56,6 @@ export const getSchema = createSelector(
export const getSortedSchemaVersions = createSelector( export const getSortedSchemaVersions = createSelector(
schemasState, schemasState,
({ currentSchemaVersions }) => sortBy(currentSchemaVersions, ['id']) ({ currentSchemaVersions }) =>
orderBy(currentSchemaVersions, ['id'], ['desc'])
); );