add copy log to clipboard button

pull/419/head
slowbackspace 5 years ago
parent fd2582dc51
commit 0add59669b

@ -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);
}
};

@ -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';
export const ADD: 'log__add' = 'log__add';
export const COPY_SUCCESS: 'log__copy_success' = 'log__copy_success';

@ -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<State, 'log'>,
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<string> => {
if (!props.log.opened) return null;
const copyBtn = (
<ButtonCopy onClick={() => props.copyToClipboard()}>
<FormattedMessage {...l10nMessages.TR_COPY_TO_CLIPBOARD} />
</ButtonCopy>
);
return (
<Wrapper>
<Click onClick={props.toggle}>
@ -76,6 +93,20 @@ const Log = (props: Props): ?React$Element<string> => {
<LogWrapper>
<ReactJson src={props.log.entries} />
</LogWrapper>
{props.log.copied ? (
<Tooltip
defaultVisible
maxWidth={285}
placement="top"
content={<FormattedMessage {...l10nMessages.TR_COPIED} />}
>
{copyBtn}
</Tooltip>
) : (
<CopyWrapper>{copyBtn}</CopyWrapper>
)
}
</Wrapper>
);
};
@ -86,5 +117,6 @@ export default connect(
}),
(dispatch: Dispatch) => ({
toggle: bindActionCreators(LogActions.toggle, dispatch),
copyToClipboard: bindActionCreators(LogActions.copyToClipboard, dispatch),
}),
)(Log);

@ -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;

@ -34,12 +34,14 @@ const Tooltip = ({
readMoreLink,
children,
enterDelayMs,
defaultVisible = false,
}) => (
<Wrapper className={className}>
<RcTooltip
arrowContent={<div className="rc-tooltip-arrow-inner" />}
placement={placement}
mouseEnterDelay={enterDelayMs || 0}
defaultVisible={defaultVisible}
overlay={() => (
<ContentWrapper>
<Content maxWidth={maxWidth}>{content}</Content>
@ -71,6 +73,7 @@ Tooltip.propTypes = {
]),
readMoreLink: PropTypes.string,
enterDelayMs: PropTypes.number,
defaultVisible: PropTypes.bool,
};
export default Tooltip;

@ -12,11 +12,13 @@ export type LogEntry = {
export type State = {
opened: boolean;
entries: Array<LogEntry>;
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;
}

Loading…
Cancel
Save