From f578bf512248c609296d2ff0ea2007a6feac561f Mon Sep 17 00:00:00 2001 From: Clemens Date: Fri, 22 Jul 2016 19:07:53 +0200 Subject: [PATCH] file upload updates contentview, editable contentloader, diffs on upload --- web/src/js/components/ContentView.jsx | 8 ++-- .../components/ContentView/ContentLoader.jsx | 8 +++- .../components/ContentView/ContentViews.jsx | 4 +- web/src/js/components/FlowView/Messages.jsx | 2 +- web/src/js/components/FlowView/ToggleEdit.jsx | 8 ++-- web/src/js/components/common/CodeEditor.jsx | 31 ++++++-------- web/src/js/ducks/ui/flow.js | 41 +++++++++++-------- web/src/js/utils.js | 14 +++++++ 8 files changed, 67 insertions(+), 49 deletions(-) diff --git a/web/src/js/components/ContentView.jsx b/web/src/js/components/ContentView.jsx index 06272627a..7c8ac510b 100644 --- a/web/src/js/components/ContentView.jsx +++ b/web/src/js/components/ContentView.jsx @@ -18,7 +18,7 @@ ContentView.propTypes = { ContentView.isContentTooLarge = msg => msg.contentLength > 1024 * 1024 * (ContentViews.ViewImage.matches(msg) ? 10 : 0.2) function ContentView(props) { - const { flow, message, contentView, selectView, displayLarge, setDisplayLarge, uploadContent, onContentChange, readonly } = props + const { flow, message, contentView, selectView, displayLarge, setDisplayLarge, lastFileUpload, uploadContent, onContentChange, content, readonly } = props if (message.contentLength === 0) { return @@ -33,15 +33,14 @@ function ContentView(props) { } const View = ContentViews[contentView] - return (
{View.textView ? ( - + ) : ( - + )}
@@ -73,6 +72,7 @@ export default connect( state => ({ contentView: state.ui.flow.contentView, displayLarge: state.ui.flow.displayLarge, + lastFileUpload: state.ui.flow.lastFileUpload }), { selectView: setContentView, diff --git a/web/src/js/components/ContentView/ContentLoader.jsx b/web/src/js/components/ContentView/ContentLoader.jsx index 1a23325cc..503ea7587 100644 --- a/web/src/js/components/ContentView/ContentLoader.jsx +++ b/web/src/js/components/ContentView/ContentLoader.jsx @@ -46,9 +46,13 @@ export default class ContentLoader extends Component { } componentWillReceiveProps(nextProps) { - if (nextProps.message !== this.props.message) { + let reload = nextProps.message !== this.props.message || nextProps.lastFileUpload !== this.props.lastFileUpload + let isUserEdit = !nextProps.readonly && nextProps.message.content + + if (isUserEdit) + this.setState({content: nextProps.message.content}) + else if(reload) this.requestContent(nextProps) - } } componentWillUnmount() { diff --git a/web/src/js/components/ContentView/ContentViews.jsx b/web/src/js/components/ContentView/ContentViews.jsx index 6c7f49009..4ae6044b4 100644 --- a/web/src/js/components/ContentView/ContentViews.jsx +++ b/web/src/js/components/ContentView/ContentViews.jsx @@ -60,10 +60,10 @@ ViewAuto.propTypes = { flow: React.PropTypes.object.isRequired, } -export function ViewAuto({ message, flow, readonly }) { +export function ViewAuto({ message, flow, readonly, lastFileUpload }) { const View = ViewAuto.findView(message) if (View.textView) { - return + return } else { return } diff --git a/web/src/js/components/FlowView/Messages.jsx b/web/src/js/components/FlowView/Messages.jsx index 0f6df8dad..a3beaf849 100644 --- a/web/src/js/components/FlowView/Messages.jsx +++ b/web/src/js/components/FlowView/Messages.jsx @@ -68,7 +68,7 @@ function ResponseLine({ flow, readonly, updateFlow }) { const Message = connect( state => ({ - flow: state.flows.byId[state.flows.selected[0]], + flow: state.ui.flow.modifiedFlow || state.flows.byId[state.flows.selected[0]], isEdit: !!state.ui.flow.modifiedFlow, }), { diff --git a/web/src/js/components/FlowView/ToggleEdit.jsx b/web/src/js/components/FlowView/ToggleEdit.jsx index cf197998f..9016348e4 100644 --- a/web/src/js/components/FlowView/ToggleEdit.jsx +++ b/web/src/js/components/FlowView/ToggleEdit.jsx @@ -10,11 +10,11 @@ ToggleEdit.propTypes = { stopEdit: PropTypes.func.isRequired, } -function ToggleEdit({ isEdit, startEdit, stopEdit, flow, old_flow }) { +function ToggleEdit({ isEdit, startEdit, stopEdit, flow, modifiedFlow }) { return (
{isEdit ? - stopEdit(flow, old_flow)}> + stopEdit(flow, modifiedFlow)}> : @@ -29,8 +29,8 @@ function ToggleEdit({ isEdit, startEdit, stopEdit, flow, old_flow }) { export default connect( state => ({ isEdit: !!state.ui.flow.modifiedFlow, - flow: state.ui.flow.modifiedFlow || state.flows.byId[state.flows.selected[0]], - old_flow: state.flows.byId[state.flows.selected[0]] + modifiedFlow: state.ui.flow.modifiedFlow || state.flows.byId[state.flows.selected[0]], + flow: state.flows.byId[state.flows.selected[0]] }), { startEdit, diff --git a/web/src/js/components/common/CodeEditor.jsx b/web/src/js/components/common/CodeEditor.jsx index ad7af39d0..95f1b98b0 100644 --- a/web/src/js/components/common/CodeEditor.jsx +++ b/web/src/js/components/common/CodeEditor.jsx @@ -3,24 +3,19 @@ import { render } from 'react-dom'; import Codemirror from 'react-codemirror'; -export default class CodeEditor extends Component{ - static propTypes = { +CodeEditor.propTypes = { content: PropTypes.string.isRequired, onChange: PropTypes.func.isRequired, - } - - constructor(props){ - super(props) - } - - render() { - let options = { - lineNumbers: true - }; - return ( -
e.stopPropagation()}> - -
- ) - } +} + +export default function CodeEditor ( { content, onChange} ){ + + let options = { + lineNumbers: true + }; + return ( +
e.stopPropagation()}> + +
+ ) } diff --git a/web/src/js/ducks/ui/flow.js b/web/src/js/ducks/ui/flow.js index e78f63731..268459559 100644 --- a/web/src/js/ducks/ui/flow.js +++ b/web/src/js/ducks/ui/flow.js @@ -1,4 +1,6 @@ import * as flowsActions from '../flows' +import { getDiff } from "../../utils" + import _ from 'lodash' export const SET_CONTENT_VIEW = 'UI_FLOWVIEW_SET_CONTENT_VIEW', @@ -6,13 +8,15 @@ export const SET_CONTENT_VIEW = 'UI_FLOWVIEW_SET_CONTENT_VIEW', SET_TAB = "UI_FLOWVIEW_SET_TAB", START_EDIT = 'UI_FLOWVIEW_START_EDIT', UPDATE_EDIT = 'UI_FLOWVIEW_UPDATE_EDIT', - STOP_EDIT = 'UI_FLOWVIEW_STOP_EDIT' + STOP_EDIT = 'UI_FLOWVIEW_STOP_EDIT', + UPLOAD_CONTENT = 'UI_FLOWVIEW_UPLOAD_CONTENT' const defaultState = { displayLarge: false, modifiedFlow: false, contentView: 'ViewAuto', + lastFileUpload: false, tab: 'request', } @@ -38,6 +42,12 @@ export default function reducer(state = defaultState, action) { modifiedFlow: false } + case UPLOAD_CONTENT: + return { + ... state, + lastFileUpload: new Date() + } + case flowsActions.SELECT: return { ...state, @@ -90,30 +100,25 @@ export function updateEdit(update) { export function uploadContent(flow, content, type){ return (dispatch) => { - dispatch(flowsActions.updateContent(flow, content, type)).then( () => { - dispatch(flowsActions.updateFlow(flow)) - dispatch({ type: STOP_EDIT }) - }) + dispatch(flowsActions.updateContent(flow, content, type)) + dispatch({ type: UPLOAD_CONTENT }) } } -export function stopEdit(modified_flow, old_flow) { - //make diff of modified_flow and old_flow +export function stopEdit(flow, modified_flow) { + let diff = getDiff(flow, modified_flow) return (dispatch) => { - let flow = {...modified_flow} - - if (flow.response.content) { - dispatch(flowsActions.updateContent(flow, flow.response.content, "response")) - flow.response = _.omit(flow.response, "content") + if (diff.response && diff.response.content) { + dispatch(flowsActions.updateContent(flow, diff.response.content, "response")) + delete diff.response.content } - if (flow.request.content) { - dispatch(flowsActions.updateContent(flow, flow.request.content, "request")) - flow.request = _.omit(flow.request, "content") + if (diff.request && diff.request.content) { + dispatch(flowsActions.updateContent(flow, diff.request.content, "request")) + delete diff.request.content } - - dispatch(flowsActions.update(flow)).then(() => { - dispatch(flowsActions.updateFlow(flow)) + dispatch(flowsActions.update(flow, diff)).then(() => { + dispatch(flowsActions.updateFlow(modified_flow)) dispatch({ type: STOP_EDIT }) }) } diff --git a/web/src/js/utils.js b/web/src/js/utils.js index eceda1959..ba07b00a1 100644 --- a/web/src/js/utils.js +++ b/web/src/js/utils.js @@ -105,3 +105,17 @@ fetchApi.put = (url, json, options) => fetchApi( ...options } ) + + +export function getDiff(obj1, obj2) { + let result = {...obj2}; + _.forIn(obj1, (value, key) => { + if(_.isEqual(obj2[key], obj1[key])) + result[key] = undefined; + else if(typeof Array.isArray(obj2[key]) && Array.isArray(obj2[key])) + result[key] = {...obj2[key]}; + else if(typeof obj2[key] == 'object' && typeof obj1[key] == 'object') + result[key] = getDiff(obj1[key], obj2[key]); + }); + return result; +}