From f0b1e9c7d97e5119e2b0cd2960f8b42f7e3b6195 Mon Sep 17 00:00:00 2001 From: GneyHabub Date: Mon, 15 Mar 2021 11:04:21 +0300 Subject: [PATCH] Refactor Abstract dynamic button to a separate component; Move buttons to the JSONViewer; Move data-saving to a hook; --- kafka-ui-react-app/src/components/App.scss | 23 ------ .../Topics/Details/Messages/MessageItem.tsx | 81 ++++--------------- .../__snapshots__/MessageItem.spec.tsx.snap | 40 --------- .../common/JSONViewer/DynamicButton.tsx | 44 ++++++++++ .../common/JSONViewer/JSONViewer.tsx | 51 +++++++++++- .../src/lib/hooks/useDataSaver.tsx | 27 +++++++ 6 files changed, 133 insertions(+), 133 deletions(-) create mode 100644 kafka-ui-react-app/src/components/common/JSONViewer/DynamicButton.tsx create mode 100644 kafka-ui-react-app/src/lib/hooks/useDataSaver.tsx diff --git a/kafka-ui-react-app/src/components/App.scss b/kafka-ui-react-app/src/components/App.scss index 98dde95019..e66343f9dd 100644 --- a/kafka-ui-react-app/src/components/App.scss +++ b/kafka-ui-react-app/src/components/App.scss @@ -36,26 +36,3 @@ $navbar-width: 250px; .react-datepicker-popper { z-index: 30 !important; } - -.topic-message-button { - &::after { - content: attr(data-title); - position: absolute; - top: -140%; - z-index: 1; - background: #F5F5F5; - color: rgb(89, 89, 89); - border-radius: 5px; - font-size: 15px; - padding: 5px 10px; - opacity: 0; - pointer-events: none; - transition: .2s opacity; - transition-delay: 0s; - } - - &:hover::after { - opacity: 1; - transition-delay: .5s; - } -} diff --git a/kafka-ui-react-app/src/components/Topics/Details/Messages/MessageItem.tsx b/kafka-ui-react-app/src/components/Topics/Details/Messages/MessageItem.tsx index d08c09bb49..abf2584d29 100644 --- a/kafka-ui-react-app/src/components/Topics/Details/Messages/MessageItem.tsx +++ b/kafka-ui-react-app/src/components/Topics/Details/Messages/MessageItem.tsx @@ -15,72 +15,19 @@ const MessageItem: React.FC = ({ offset, timestamp, content, -}) => { - const copyData = () => { - if (navigator.clipboard) - navigator.clipboard.writeText(JSON.stringify(content || {})); - }; - const saveFile = () => { - let extension = 'json'; - if (typeof content === 'string') { - try { - JSON.parse(content); - } catch (e) { - extension = 'txt'; - } - } - const dataStr = `data:text/json;charset=utf-8,${encodeURIComponent( - JSON.stringify(content || {}) - )}`; - const downloadAnchorNode = document.createElement('a'); - downloadAnchorNode.setAttribute('href', dataStr); - downloadAnchorNode.setAttribute( - 'download', - `topic-message[${timestamp}].${extension}` - ); - document.body.appendChild(downloadAnchorNode); - downloadAnchorNode.click(); - downloadAnchorNode.remove(); - }; - - const buttonStyle = { - height: '30px', - }; - const buttonClasses = 'button is-link is-outlined topic-message-button'; - return ( - - {format(timestamp, 'yyyy-MM-dd HH:mm:ss')} - {offset} - {partition} - - {content && ( -
-
- - -
- -
- )} - - - ); -}; +}) => ( + + {format(timestamp, 'yyyy-MM-dd HH:mm:ss')} + {offset} + {partition} + + {content && ( +
+ +
+ )} + + +); export default MessageItem; diff --git a/kafka-ui-react-app/src/components/Topics/Details/Messages/__test__/__snapshots__/MessageItem.spec.tsx.snap b/kafka-ui-react-app/src/components/Topics/Details/Messages/__test__/__snapshots__/MessageItem.spec.tsx.snap index 8038e1d230..eacbc5f3d2 100644 --- a/kafka-ui-react-app/src/components/Topics/Details/Messages/__test__/__snapshots__/MessageItem.spec.tsx.snap +++ b/kafka-ui-react-app/src/components/Topics/Details/Messages/__test__/__snapshots__/MessageItem.spec.tsx.snap @@ -37,46 +37,6 @@ exports[`MessageItem when content is defined matches snapshot 1`] = ` } >
-
- - -
void; + classes?: string; + title: string; + style?: { [key: string]: string | number }; + text: { + default: string; + dynamic: string; + }; +} + +const DynamicButton: React.FC = ({ + callback, + classes, + title, + style, + text, + children, +}) => { + const [buttonText, setButtonText] = React.useState(text.default); + let timeout: number; + const clickHandler = () => { + callback(); + setButtonText(text.dynamic); + timeout = window.setTimeout(() => setButtonText(text.default), 3000); + }; + React.useEffect(() => () => window.clearTimeout(timeout), [callback]); + return ( + + ); +}; + +export default DynamicButton; diff --git a/kafka-ui-react-app/src/components/common/JSONViewer/JSONViewer.tsx b/kafka-ui-react-app/src/components/common/JSONViewer/JSONViewer.tsx index 6627e2d072..6eca1ddac3 100644 --- a/kafka-ui-react-app/src/components/common/JSONViewer/JSONViewer.tsx +++ b/kafka-ui-react-app/src/components/common/JSONViewer/JSONViewer.tsx @@ -1,6 +1,8 @@ import React from 'react'; import JSONTree from 'react-json-tree'; +import useDataSaver from 'lib/hooks/useDataSaver'; import theme from './themes/google'; +import DynamicButton from './DynamicButton'; interface JSONViewerProps { data: { @@ -8,8 +10,51 @@ interface JSONViewerProps { }; } -const JSONViewer: React.FC = ({ data }) => ( - true} hideRoot /> -); +const JSONViewer: React.FC = ({ data }) => { + const { copyToClipboard, saveFile } = useDataSaver(); + const copyButtonHandler = () => { + copyToClipboard(JSON.stringify(data)); + }; + const buttonClasses = 'button is-link is-outlined is-small is-centered'; + return ( +
+
+ + + + + + +
+ true} + hideRoot + /> +
+ ); +}; export default JSONViewer; diff --git a/kafka-ui-react-app/src/lib/hooks/useDataSaver.tsx b/kafka-ui-react-app/src/lib/hooks/useDataSaver.tsx new file mode 100644 index 0000000000..3fc23a168a --- /dev/null +++ b/kafka-ui-react-app/src/lib/hooks/useDataSaver.tsx @@ -0,0 +1,27 @@ +const useDataSaver = () => { + const copyToClipboard = (content: string) => { + if (navigator.clipboard) navigator.clipboard.writeText(content); + }; + + const saveFile = (content: string, fileName: string) => { + let extension = 'json'; + try { + JSON.parse(content); + } catch (e) { + extension = 'txt'; + } + const dataStr = `data:text/json;charset=utf-8,${encodeURIComponent( + content + )}`; + const downloadAnchorNode = document.createElement('a'); + downloadAnchorNode.setAttribute('href', dataStr); + downloadAnchorNode.setAttribute('download', `${fileName}.${extension}`); + document.body.appendChild(downloadAnchorNode); + downloadAnchorNode.click(); + downloadAnchorNode.remove(); + }; + + return { copyToClipboard, saveFile }; +}; + +export default useDataSaver;