MessageContent.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import React from 'react';
  2. import EditorViewer from 'components/common/EditorViewer/EditorViewer';
  3. import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
  4. import { SchemaType, TopicMessageTimestampTypeEnum } from 'generated-sources';
  5. import { formatTimestamp } from 'lib/dateTimeHelpers';
  6. import * as S from './MessageContent.styled';
  7. type Tab = 'key' | 'content' | 'headers';
  8. export interface MessageContentProps {
  9. messageKey?: string;
  10. messageKeyFormat?: string;
  11. messageContent?: string;
  12. messageContentFormat?: string;
  13. headers?: { [key: string]: string | undefined };
  14. timestamp?: Date;
  15. timestampType?: TopicMessageTimestampTypeEnum;
  16. }
  17. const MessageContent: React.FC<MessageContentProps> = ({
  18. messageKey,
  19. messageKeyFormat,
  20. messageContent,
  21. messageContentFormat,
  22. headers,
  23. timestamp,
  24. timestampType,
  25. }) => {
  26. const [activeTab, setActiveTab] = React.useState<Tab>('content');
  27. const activeTabContent = () => {
  28. switch (activeTab) {
  29. case 'content':
  30. return messageContent;
  31. case 'key':
  32. return messageKey;
  33. default:
  34. return JSON.stringify(headers);
  35. }
  36. };
  37. const handleKeyTabClick = (e: React.MouseEvent) => {
  38. e.preventDefault();
  39. setActiveTab('key');
  40. };
  41. const handleContentTabClick = (e: React.MouseEvent) => {
  42. e.preventDefault();
  43. setActiveTab('content');
  44. };
  45. const handleHeadersTabClick = (e: React.MouseEvent) => {
  46. e.preventDefault();
  47. setActiveTab('headers');
  48. };
  49. const keySize = new TextEncoder().encode(messageKey).length;
  50. const contentSize = new TextEncoder().encode(messageContent).length;
  51. const contentType =
  52. messageContent && messageContent.trim().startsWith('{')
  53. ? SchemaType.JSON
  54. : SchemaType.PROTOBUF;
  55. return (
  56. <S.Wrapper>
  57. <td colSpan={10}>
  58. <S.Section>
  59. <S.ContentBox>
  60. <S.Tabs>
  61. <S.Tab
  62. type="button"
  63. $active={activeTab === 'key'}
  64. onClick={handleKeyTabClick}
  65. >
  66. Key
  67. </S.Tab>
  68. <S.Tab
  69. $active={activeTab === 'content'}
  70. type="button"
  71. onClick={handleContentTabClick}
  72. >
  73. Value
  74. </S.Tab>
  75. <S.Tab
  76. $active={activeTab === 'headers'}
  77. type="button"
  78. onClick={handleHeadersTabClick}
  79. >
  80. Headers
  81. </S.Tab>
  82. </S.Tabs>
  83. <EditorViewer
  84. data={activeTabContent() || ''}
  85. maxLines={28}
  86. schemaType={contentType}
  87. />
  88. </S.ContentBox>
  89. <S.MetadataWrapper>
  90. <S.Metadata>
  91. <S.MetadataLabel>Timestamp</S.MetadataLabel>
  92. <span>
  93. <S.MetadataValue>{formatTimestamp(timestamp)}</S.MetadataValue>
  94. <S.MetadataMeta>Timestamp type: {timestampType}</S.MetadataMeta>
  95. </span>
  96. </S.Metadata>
  97. <S.Metadata>
  98. <S.MetadataLabel>Value</S.MetadataLabel>
  99. <span>
  100. <S.MetadataValue>{messageContentFormat}</S.MetadataValue>
  101. <S.MetadataMeta>
  102. Size: <BytesFormatted value={contentSize} />
  103. </S.MetadataMeta>
  104. </span>
  105. </S.Metadata>
  106. <S.Metadata>
  107. <S.MetadataLabel>Key</S.MetadataLabel>
  108. <span>
  109. <S.MetadataValue>{messageKeyFormat}</S.MetadataValue>
  110. <S.MetadataMeta>
  111. Size: <BytesFormatted value={keySize} />
  112. </S.MetadataMeta>
  113. </span>
  114. </S.Metadata>
  115. </S.MetadataWrapper>
  116. </S.Section>
  117. </td>
  118. </S.Wrapper>
  119. );
  120. };
  121. export default MessageContent;