From 0add59669bf4a7ce20ff70f8a1605b46bc8dcfde Mon Sep 17 00:00:00 2001 From: slowbackspace Date: Mon, 4 Mar 2019 12:52:26 +0100 Subject: [PATCH] add copy log to clipboard button --- src/actions/LogActions.js | 17 ++++++++++++++ src/actions/constants/log.js | 3 ++- src/components/Log/index.js | 34 +++++++++++++++++++++++++++- src/components/Log/index.messages.js | 8 +++++++ src/components/Tooltip/index.js | 3 +++ src/reducers/LogReducer.js | 9 ++++++++ 6 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/actions/LogActions.js b/src/actions/LogActions.js index 5e1bf6a7..a6fd8427 100644 --- a/src/actions/LogActions.js +++ b/src/actions/LogActions.js @@ -1,6 +1,7 @@ /* @flow */ import * as LOG from 'actions/constants/log'; +import copy from 'copy-to-clipboard'; import type { Action, ThunkAction, GetState, Dispatch, @@ -11,6 +12,8 @@ export type LogAction = { type: typeof LOG.OPEN, } | { type: typeof LOG.CLOSE, +} | { + type: typeof LOG.COPY_SUCCESS, } | { type: typeof LOG.ADD, payload: LogEntry @@ -38,3 +41,17 @@ export const add = (type: string, message: any): Action => ({ message, }, }); + +export const copyToClipboard = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { + const { entries } = getState().log; + try { + const res = copy(JSON.stringify(entries)); + if (res) { + dispatch({ + type: LOG.COPY_SUCCESS, + }); + } + } catch (err) { + console.error(err); + } +}; diff --git a/src/actions/constants/log.js b/src/actions/constants/log.js index a08a84cf..c666cbba 100644 --- a/src/actions/constants/log.js +++ b/src/actions/constants/log.js @@ -3,4 +3,5 @@ export const OPEN: 'log__open' = 'log__open'; export const CLOSE: 'log__close' = 'log__close'; -export const ADD: 'log__add' = 'log__add'; \ No newline at end of file +export const ADD: 'log__add' = 'log__add'; +export const COPY_SUCCESS: 'log__copy_success' = 'log__copy_success'; \ No newline at end of file diff --git a/src/components/Log/index.js b/src/components/Log/index.js index 1b3c4125..8829f6c7 100644 --- a/src/components/Log/index.js +++ b/src/components/Log/index.js @@ -5,6 +5,8 @@ import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import colors from 'config/colors'; import { H2 } from 'components/Heading'; +import Button from 'components/Button'; +import Tooltip from 'components/Tooltip'; import ReactJson from 'react-json-view'; import Icon from 'components/Icon'; import P from 'components/Paragraph'; @@ -18,7 +20,8 @@ import l10nMessages from './index.messages'; type Props = { log: $ElementType, - toggle: typeof LogActions.toggle + toggle: typeof LogActions.toggle, + copyToClipboard: typeof LogActions.copyToClipboard } const Wrapper = styled.div` @@ -60,8 +63,22 @@ const LogWrapper = styled.div` overflow: scroll; `; +const CopyWrapper = styled.div` +`; + +const ButtonCopy = styled(Button)` + margin-top: 10px; + max-width: 200px; +`; + const Log = (props: Props): ?React$Element => { if (!props.log.opened) return null; + + const copyBtn = ( + props.copyToClipboard()}> + + + ); return ( @@ -76,6 +93,20 @@ const Log = (props: Props): ?React$Element => { + {props.log.copied ? ( + } + > + + {copyBtn} + + ) : ( + {copyBtn} + ) + } ); }; @@ -86,5 +117,6 @@ export default connect( }), (dispatch: Dispatch) => ({ toggle: bindActionCreators(LogActions.toggle, dispatch), + copyToClipboard: bindActionCreators(LogActions.copyToClipboard, dispatch), }), )(Log); \ No newline at end of file diff --git a/src/components/Log/index.messages.js b/src/components/Log/index.messages.js index f0dd2940..6a4d6920 100644 --- a/src/components/Log/index.messages.js +++ b/src/components/Log/index.messages.js @@ -12,6 +12,14 @@ const definedMessages: Messages = defineMessages({ defaultMessage: 'Log', description: 'application event and error', }, + TR_COPY_TO_CLIPBOARD: { + id: 'TR_COPY_TO_CLIPBOARD', + defaultMessage: 'Copy to clipboard', + }, + TR_COPIED: { + id: 'TR_COPIED', + defaultMessage: 'Copied!', + }, }); export default definedMessages; \ No newline at end of file diff --git a/src/components/Tooltip/index.js b/src/components/Tooltip/index.js index 3186f2a7..a0658e29 100644 --- a/src/components/Tooltip/index.js +++ b/src/components/Tooltip/index.js @@ -34,12 +34,14 @@ const Tooltip = ({ readMoreLink, children, enterDelayMs, + defaultVisible = false, }) => ( } placement={placement} mouseEnterDelay={enterDelayMs || 0} + defaultVisible={defaultVisible} overlay={() => ( {content} @@ -71,6 +73,7 @@ Tooltip.propTypes = { ]), readMoreLink: PropTypes.string, enterDelayMs: PropTypes.number, + defaultVisible: PropTypes.bool, }; export default Tooltip; diff --git a/src/reducers/LogReducer.js b/src/reducers/LogReducer.js index ac5998e7..2cf643be 100644 --- a/src/reducers/LogReducer.js +++ b/src/reducers/LogReducer.js @@ -12,11 +12,13 @@ export type LogEntry = { export type State = { opened: boolean; entries: Array; + copied: boolean } export const initialState: State = { opened: false, entries: [], + copied: false, }; @@ -32,6 +34,7 @@ export default (state: State = initialState, action: Action): State => { return { ...state, opened: false, + copied: false, }; case LOG.ADD: @@ -40,6 +43,12 @@ export default (state: State = initialState, action: Action): State => { entries: state.entries.concat([action.payload]), }; + case LOG.COPY_SUCCESS: + return { + ...state, + copied: true, + }; + default: return state; }