file upload updates contentview, editable contentloader, diffs on upload

This commit is contained in:
Clemens 2016-07-22 19:07:53 +02:00
parent 70ca10b423
commit f578bf5122
8 changed files with 67 additions and 49 deletions

View File

@ -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 <MetaViews.ContentEmpty {...props}/>
@ -33,15 +33,14 @@ function ContentView(props) {
}
const View = ContentViews[contentView]
return (
<div>
{View.textView ? (
<ContentLoader flow={flow} message={message}>
<ContentLoader flow={flow} lastFileUpload={lastFileUpload} readonly={readonly} message={message}>
<View readonly={readonly} onChange={onContentChange} content="" />
</ContentLoader>
) : (
<View flow={flow} readonly={readonly} message={message} />
<View flow={flow} lastFileUpload={lastFileUpload} readonly={readonly} content={content} message={message} />
)}
<div className="view-options text-center">
<ViewSelector onSelectView={selectView} active={View} message={message}/>
@ -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,

View File

@ -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() {

View File

@ -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 <ContentLoader message={message} flow={flow}><View readonly={readonly} content="" /></ContentLoader>
return <ContentLoader message={message} lastFileUpload={lastFileUpload} flow={flow}><View readonly={readonly} content="" /></ContentLoader>
} else {
return <View readonly={readonly} message={message} flow={flow} />
}

View File

@ -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,
}),
{

View File

@ -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 (
<div className="edit-flow-container">
{isEdit ?
<a className="edit-flow" onClick={() => stopEdit(flow, old_flow)}>
<a className="edit-flow" onClick={() => stopEdit(flow, modifiedFlow)}>
<i className="fa fa-check"/>
</a>
:
@ -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,

View File

@ -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 (
<div onKeyDown={e => e.stopPropagation()}>
<Codemirror value={this.props.content} onChange={this.props.onChange} options={options}/>
</div>
)
}
}
export default function CodeEditor ( { content, onChange} ){
let options = {
lineNumbers: true
};
return (
<div onKeyDown={e => e.stopPropagation()}>
<Codemirror value={content} onChange={onChange} options={options}/>
</div>
)
}

View File

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

View File

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