From 62f3304bc41bc9b5046d70ecc48fff3de36859b8 Mon Sep 17 00:00:00 2001 From: Maksym Bykovskyy Date: Thu, 27 Feb 2020 12:22:43 -0800 Subject: [PATCH] Added view in try-michelson link --- .../client/src/components/output-tab.tsx | 38 ++++---- .../client/src/components/output-toolbar.tsx | 92 ++++++++----------- .../client/src/components/toolbar.tsx | 65 +++++++++++++ tools/webide/packages/client/src/index.css | 2 +- .../client/src/redux/actions/compile.ts | 10 +- .../client/src/redux/actions/deploy.ts | 10 +- .../client/src/redux/actions/dry-run.ts | 8 +- .../src/redux/actions/evaluate-function.ts | 10 +- .../src/redux/actions/evaluate-value.ts | 10 +- .../packages/client/src/redux/result.ts | 20 +++- 10 files changed, 178 insertions(+), 87 deletions(-) create mode 100644 tools/webide/packages/client/src/components/toolbar.tsx diff --git a/tools/webide/packages/client/src/components/output-tab.tsx b/tools/webide/packages/client/src/components/output-tab.tsx index 22e0a397c..147942910 100644 --- a/tools/webide/packages/client/src/components/output-tab.tsx +++ b/tools/webide/packages/client/src/components/output-tab.tsx @@ -7,6 +7,7 @@ import { AppState } from '../redux/app'; import { CommandState } from '../redux/command'; import { DoneLoadingAction, LoadingState } from '../redux/loading'; import { ResultState } from '../redux/result'; +import { Command } from '../redux/types'; import { OutputToolbarComponent } from './output-toolbar'; const Container = styled.div<{ visible?: boolean }>` @@ -43,7 +44,7 @@ const CancelButton = styled.div` const Output = styled.div` flex: 1; - padding: 0 0.5em 0.5em 0.5em; + padding: 0.5em; display: flex; overflow: scroll; /* This font size is used to calcuate spinner size */ @@ -81,20 +82,18 @@ function copyOutput(el: HTMLElement | null) { } } -function downloadOutput(el: HTMLElement | null) { - if (el) { - const anchor = document.createElement('a'); - anchor.setAttribute( - 'href', - 'data:text/plain;charset=utf-8,' + encodeURIComponent(el.innerHTML) - ); - anchor.setAttribute('download', 'output.txt'); +function downloadOutput(output: string) { + const anchor = document.createElement('a'); + anchor.setAttribute( + 'href', + `data:text/plain;charset=utf-8,${encodeURIComponent(output)}` + ); + anchor.setAttribute('download', 'output.txt'); - anchor.style.display = 'none'; - document.body.appendChild(anchor); - anchor.click(); - document.body.removeChild(anchor); - } + anchor.style.display = 'none'; + document.body.appendChild(anchor); + anchor.click(); + document.body.removeChild(anchor); } export const OutputTabComponent = (props: { @@ -107,6 +106,9 @@ export const OutputTabComponent = (props: { const contract = useSelector( state => state.result.contract ); + const command = useSelector( + state => state.result.command + ); const loading = useSelector(state => state.loading); @@ -132,10 +134,14 @@ export const OutputTabComponent = (props: { return ( - {!(loading.loading || output.length === 0) && ( + {!( + loading.loading || + output.length === 0 || + command !== Command.Compile + ) && ( copyOutput(preRef.current)} - onDownload={() => downloadOutput(preRef.current)} + onDownload={() => downloadOutput(output)} > )} diff --git a/tools/webide/packages/client/src/components/output-toolbar.tsx b/tools/webide/packages/client/src/components/output-toolbar.tsx index a258352ce..871dcb873 100644 --- a/tools/webide/packages/client/src/components/output-toolbar.tsx +++ b/tools/webide/packages/client/src/components/output-toolbar.tsx @@ -1,78 +1,58 @@ import { faCopy, faDownload } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import React from 'react'; +import { useSelector } from 'react-redux'; import styled from 'styled-components'; +import { AppState } from '../redux/app'; +import { ResultState } from '../redux/result'; +import { Item, Toolbar } from './toolbar'; import { Tooltip } from './tooltip'; -const Container = styled.div` - display: flex; - justify-content: flex-start; - padding: 0.2em 0.5em; - z-index: 3; +const Divider = styled.div` + display: block; + background-color: rgba(0, 0, 0, 0.12); + height: 20px; + width: 1px; + margin: 0 3px; `; -const Action = styled.div` - z-index: 3; - position: relative; - margin: 4px 6px; - cursor: pointer; - - opacity: 0.5; - color: #444; - - ::before { - content: ''; - display: block; - position: absolute; - z-index: -1; - bottom: -4px; - left: -4px; - right: -4px; - top: -4px; - border-radius: 4px; - background: none; - box-sizing: border-box; - opacity: 0; - transform: scale(0); - transition-property: transform, opacity; - transition-duration: 0.15s; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - } - - :hover::before { - background-color: rgba(32, 33, 36, 0.059); - opacity: 1; - transform: scale(1); - } - - :hover { - opacity: 1; - } - - &:first-child { - margin-left: 0; - } - - &:last-child { - margin-right: 0; - } +const Link = styled.a` + font-size: 0.8em; + color: var(--blue); + opacity: 1; `; export const OutputToolbarComponent = (props: { onCopy?: () => void; onDownload?: () => void; }) => { + const output = useSelector( + state => state.result.output + ); + return ( - - props.onCopy && props.onCopy()}> + + props.onCopy && props.onCopy()}> Copy - - props.onDownload && props.onDownload()}> + + props.onDownload && props.onDownload()}> Download - - + + + + + View in Try-Michelson IDE + + + ); }; diff --git a/tools/webide/packages/client/src/components/toolbar.tsx b/tools/webide/packages/client/src/components/toolbar.tsx new file mode 100644 index 000000000..ef3386fab --- /dev/null +++ b/tools/webide/packages/client/src/components/toolbar.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import styled from 'styled-components'; + +const Container = styled.div` + display: flex; + align-items: center; + padding: 0.2em 0.5em; + z-index: 3; +`; + +export const Group = styled.div` + display: flex; + align-items: center; +`; + +export const Item = styled.div` + z-index: 3; + position: relative; + margin: 4px 6px; + cursor: pointer; + + opacity: 0.5; + color: #444; + + ::before { + content: ''; + display: block; + position: absolute; + z-index: -1; + bottom: -4px; + left: -4px; + right: -4px; + top: -4px; + border-radius: 4px; + background: none; + box-sizing: border-box; + opacity: 0; + transform: scale(0); + transition-property: transform, opacity; + transition-duration: 0.15s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + } + + :hover::before { + background-color: rgba(32, 33, 36, 0.059); + opacity: 1; + transform: scale(1); + } + + :hover { + opacity: 1; + } + + &:first-child { + margin-left: 0; + } + + &:last-child { + margin-right: 0; + } +`; + +export const Toolbar = (props: any) => { + return {props.children}; +}; diff --git a/tools/webide/packages/client/src/index.css b/tools/webide/packages/client/src/index.css index 1f3296c3f..adb1df287 100644 --- a/tools/webide/packages/client/src/index.css +++ b/tools/webide/packages/client/src/index.css @@ -48,7 +48,7 @@ --font_ghost_weight: 700; --font_ghost_color: rgba(153, 153, 153, 0.5); /* or #CFCFCF */ - --content_height: 85vh; + --content_height: 84vh; --tooltip_foreground: white; --tooltip_background: rgba(0, 0, 0, 0.75) /*#404040*/; diff --git a/tools/webide/packages/client/src/redux/actions/compile.ts b/tools/webide/packages/client/src/redux/actions/compile.ts index 2c3f21a29..cd2ed98db 100644 --- a/tools/webide/packages/client/src/redux/actions/compile.ts +++ b/tools/webide/packages/client/src/redux/actions/compile.ts @@ -4,6 +4,7 @@ import { compileContract, getErrorMessage } from '../../services/api'; import { AppState } from '../app'; import { DoneLoadingAction, UpdateLoadingAction } from '../loading'; import { ChangeOutputAction } from '../result'; +import { Command } from '../types'; import { CancellableAction } from './cancellable'; export class CompileAction extends CancellableAction { @@ -24,13 +25,18 @@ export class CompileAction extends CancellableAction { return; } - dispatch({ ...new ChangeOutputAction(michelsonCode.result) }); + dispatch({ + ...new ChangeOutputAction(michelsonCode.result, Command.Compile) + }); } catch (ex) { if (this.isCancelled()) { return; } dispatch({ - ...new ChangeOutputAction(`Error: ${getErrorMessage(ex)}`) + ...new ChangeOutputAction( + `Error: ${getErrorMessage(ex)}`, + Command.Compile + ) }); } diff --git a/tools/webide/packages/client/src/redux/actions/deploy.ts b/tools/webide/packages/client/src/redux/actions/deploy.ts index ffc62c966..5fc9dcf1d 100644 --- a/tools/webide/packages/client/src/redux/actions/deploy.ts +++ b/tools/webide/packages/client/src/redux/actions/deploy.ts @@ -7,6 +7,7 @@ import { AppState } from '../app'; import { MichelsonFormat } from '../compile'; import { DoneLoadingAction, UpdateLoadingAction } from '../loading'; import { ChangeContractAction, ChangeOutputAction } from '../result'; +import { Command } from '../types'; import { CancellableAction } from './cancellable'; Tezos.setProvider({ @@ -85,13 +86,18 @@ export class DeployAction extends CancellableAction { return; } - dispatch({ ...new ChangeContractAction(contract.address) }); + dispatch({ + ...new ChangeContractAction(contract.address, Command.Deploy) + }); } catch (ex) { if (this.isCancelled()) { return; } dispatch({ - ...new ChangeOutputAction(`Error: ${getErrorMessage(ex)}`) + ...new ChangeOutputAction( + `Error: ${getErrorMessage(ex)}`, + Command.Deploy + ) }); } diff --git a/tools/webide/packages/client/src/redux/actions/dry-run.ts b/tools/webide/packages/client/src/redux/actions/dry-run.ts index 9b51a58ff..515435647 100644 --- a/tools/webide/packages/client/src/redux/actions/dry-run.ts +++ b/tools/webide/packages/client/src/redux/actions/dry-run.ts @@ -4,6 +4,7 @@ import { dryRun, getErrorMessage } from '../../services/api'; import { AppState } from '../app'; import { DoneLoadingAction, UpdateLoadingAction } from '../loading'; import { ChangeOutputAction } from '../result'; +import { Command } from '../types'; import { CancellableAction } from './cancellable'; export class DryRunAction extends CancellableAction { @@ -25,13 +26,16 @@ export class DryRunAction extends CancellableAction { if (this.isCancelled()) { return; } - dispatch({ ...new ChangeOutputAction(result.output) }); + dispatch({ ...new ChangeOutputAction(result.output, Command.DryRun) }); } catch (ex) { if (this.isCancelled()) { return; } dispatch({ - ...new ChangeOutputAction(`Error: ${getErrorMessage(ex)}`) + ...new ChangeOutputAction( + `Error: ${getErrorMessage(ex)}`, + Command.DryRun + ) }); } diff --git a/tools/webide/packages/client/src/redux/actions/evaluate-function.ts b/tools/webide/packages/client/src/redux/actions/evaluate-function.ts index 85871ebda..ab7b0053f 100644 --- a/tools/webide/packages/client/src/redux/actions/evaluate-function.ts +++ b/tools/webide/packages/client/src/redux/actions/evaluate-function.ts @@ -4,6 +4,7 @@ import { getErrorMessage, runFunction } from '../../services/api'; import { AppState } from '../app'; import { DoneLoadingAction, UpdateLoadingAction } from '../loading'; import { ChangeOutputAction } from '../result'; +import { Command } from '../types'; import { CancellableAction } from './cancellable'; export class EvaluateFunctionAction extends CancellableAction { @@ -27,13 +28,18 @@ export class EvaluateFunctionAction extends CancellableAction { if (this.isCancelled()) { return; } - dispatch({ ...new ChangeOutputAction(result.output) }); + dispatch({ + ...new ChangeOutputAction(result.output, Command.EvaluateFunction) + }); } catch (ex) { if (this.isCancelled()) { return; } dispatch({ - ...new ChangeOutputAction(`Error: ${getErrorMessage(ex)}`) + ...new ChangeOutputAction( + `Error: ${getErrorMessage(ex)}`, + Command.EvaluateFunction + ) }); } diff --git a/tools/webide/packages/client/src/redux/actions/evaluate-value.ts b/tools/webide/packages/client/src/redux/actions/evaluate-value.ts index 16f46696d..765476884 100644 --- a/tools/webide/packages/client/src/redux/actions/evaluate-value.ts +++ b/tools/webide/packages/client/src/redux/actions/evaluate-value.ts @@ -4,6 +4,7 @@ import { evaluateValue, getErrorMessage } from '../../services/api'; import { AppState } from '../app'; import { DoneLoadingAction, UpdateLoadingAction } from '../loading'; import { ChangeOutputAction } from '../result'; +import { Command } from '../types'; import { CancellableAction } from './cancellable'; export class EvaluateValueAction extends CancellableAction { @@ -28,13 +29,18 @@ export class EvaluateValueAction extends CancellableAction { return; } - dispatch({ ...new ChangeOutputAction(result.code) }); + dispatch({ + ...new ChangeOutputAction(result.code, Command.EvaluateValue) + }); } catch (ex) { if (this.isCancelled()) { return; } dispatch({ - ...new ChangeOutputAction(`Error: ${getErrorMessage(ex)}`) + ...new ChangeOutputAction( + `Error: ${getErrorMessage(ex)}`, + Command.EvaluateValue + ) }); } diff --git a/tools/webide/packages/client/src/redux/result.ts b/tools/webide/packages/client/src/redux/result.ts index 54315a948..3fcca74c7 100644 --- a/tools/webide/packages/client/src/redux/result.ts +++ b/tools/webide/packages/client/src/redux/result.ts @@ -1,26 +1,36 @@ +import { Command } from './types'; + export enum ActionType { ChangeOutput = 'result-change-output', ChangeContract = 'result-change-contract' } export interface ResultState { + command: Command; output: string; contract: string; } export class ChangeOutputAction { public readonly type = ActionType.ChangeOutput; - constructor(public payload: ResultState['output']) {} + constructor( + public output: ResultState['output'], + public command: ResultState['command'] + ) {} } export class ChangeContractAction { public readonly type = ActionType.ChangeContract; - constructor(public payload: ResultState['contract']) {} + constructor( + public contract: ResultState['contract'], + public command: ResultState['command'] + ) {} } type Action = ChangeOutputAction | ChangeContractAction; const DEFAULT_STATE: ResultState = { + command: Command.Compile, output: '', contract: '' }; @@ -30,13 +40,15 @@ export default (state = DEFAULT_STATE, action: Action): ResultState => { case ActionType.ChangeOutput: return { ...state, - output: action.payload + output: action.output, + command: action.command }; case ActionType.ChangeContract: return { ...state, output: DEFAULT_STATE.output, - contract: action.payload + contract: action.contract, + command: action.command }; } return state;