mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-26 18:18:25 +00:00
add view all button, add dropdown for contentviews
This commit is contained in:
parent
bcc496527e
commit
34fe391afb
@ -65,6 +65,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.view-options {
|
.view-options {
|
||||||
|
margin-bottom: 10px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import * as MetaViews from './ContentView/MetaViews'
|
|||||||
import ViewSelector from './ContentView/ViewSelector'
|
import ViewSelector from './ContentView/ViewSelector'
|
||||||
import UploadContentButton from './ContentView/UploadContentButton'
|
import UploadContentButton from './ContentView/UploadContentButton'
|
||||||
import DownloadContentButton from './ContentView/DownloadContentButton'
|
import DownloadContentButton from './ContentView/DownloadContentButton'
|
||||||
|
import ShowFullContentButton from './ContentView/ShowFullContentButton'
|
||||||
|
|
||||||
import { setContentView, displayLarge, updateEdit } from '../ducks/ui/flow'
|
import { setContentView, displayLarge, updateEdit } from '../ducks/ui/flow'
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ ContentView.propTypes = {
|
|||||||
ContentView.isContentTooLarge = msg => msg.contentLength > 1024 * 1024 * (ContentViews.ViewImage.matches(msg) ? 10 : 0.2)
|
ContentView.isContentTooLarge = msg => msg.contentLength > 1024 * 1024 * (ContentViews.ViewImage.matches(msg) ? 10 : 0.2)
|
||||||
|
|
||||||
function ContentView(props) {
|
function ContentView(props) {
|
||||||
const { flow, message, contentView, isDisplayLarge, displayLarge, uploadContent, onContentChange, readonly } = props
|
const { flow, message, contentView, isDisplayLarge, displayLarge, uploadContent, onContentChange, readonly, contentViewDescription } = props
|
||||||
|
|
||||||
if (message.contentLength === 0 && readonly) {
|
if (message.contentLength === 0 && readonly) {
|
||||||
return <MetaViews.ContentEmpty {...props}/>
|
return <MetaViews.ContentEmpty {...props}/>
|
||||||
@ -37,13 +38,15 @@ function ContentView(props) {
|
|||||||
return (
|
return (
|
||||||
<div className="contentview">
|
<div className="contentview">
|
||||||
<View flow={flow} message={message} contentView={contentView} readonly={readonly} onChange={onContentChange}/>
|
<View flow={flow} message={message} contentView={contentView} readonly={readonly} onChange={onContentChange}/>
|
||||||
|
<ShowFullContentButton/>
|
||||||
<div className="view-options text-center">
|
<div className="view-options">
|
||||||
<ViewSelector message={message}/>
|
<ViewSelector message={message}/>
|
||||||
|
|
||||||
<DownloadContentButton flow={flow} message={message}/>
|
<DownloadContentButton flow={flow} message={message}/>
|
||||||
|
|
||||||
<UploadContentButton uploadContent={uploadContent}/>
|
<UploadContentButton uploadContent={uploadContent}/>
|
||||||
|
|
||||||
|
<span>{contentViewDescription}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@ -53,6 +56,7 @@ export default connect(
|
|||||||
state => ({
|
state => ({
|
||||||
contentView: state.ui.flow.contentView,
|
contentView: state.ui.flow.contentView,
|
||||||
isDisplayLarge: state.ui.flow.displayLarge,
|
isDisplayLarge: state.ui.flow.displayLarge,
|
||||||
|
contentViewDescription: state.ui.flow.viewDescription
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
displayLarge,
|
displayLarge,
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes, Component } from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { setContentViewDescription, setShowFullContent } from '../../ducks/ui/flow'
|
||||||
import ContentLoader from './ContentLoader'
|
import ContentLoader from './ContentLoader'
|
||||||
import { MessageUtils } from '../../flow/utils'
|
import { MessageUtils } from '../../flow/utils'
|
||||||
import CodeEditor from './CodeEditor'
|
import CodeEditor from './CodeEditor'
|
||||||
@ -27,17 +29,38 @@ function Edit({ content, onChange }) {
|
|||||||
}
|
}
|
||||||
Edit = ContentLoader(Edit)
|
Edit = ContentLoader(Edit)
|
||||||
|
|
||||||
|
class ViewServer extends Component {
|
||||||
|
constructor(props){
|
||||||
|
super(props)
|
||||||
|
this.maxLines = 80
|
||||||
|
}
|
||||||
|
|
||||||
function ViewServer(props){
|
componentWillMount(){
|
||||||
const {content, contentView, message} = props
|
this.setContentView(this.props)
|
||||||
let data = JSON.parse(content)
|
}
|
||||||
|
componentWillReceiveProps(nextProps){
|
||||||
|
this.setContentView(nextProps)
|
||||||
|
}
|
||||||
|
setContentView(props){
|
||||||
|
try {
|
||||||
|
this.data = JSON.parse(props.content)
|
||||||
|
}catch(err) {
|
||||||
|
this.data= {lines: [], description: err.message}
|
||||||
|
}
|
||||||
|
|
||||||
|
props.setContentViewDescription(props.contentView != this.data.description ? this.data.description : '')
|
||||||
|
|
||||||
|
let isFullContentShown = this.data.lines.length < this.maxLines
|
||||||
|
if (isFullContentShown) props.setShowFullContent(true)
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const {content, contentView, message} = this.props
|
||||||
|
|
||||||
|
let lines = this.props.showFullContent ? this.data.lines : this.data.lines.slice(0, this.maxLines)
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{contentView != data.description &&
|
|
||||||
<div className="alert alert-warning">{data.description}</div>
|
|
||||||
}
|
|
||||||
<pre>
|
<pre>
|
||||||
{data.lines.map((line, i) =>
|
{lines.map((line, i) =>
|
||||||
<div key={`line${i}`}>
|
<div key={`line${i}`}>
|
||||||
{line.map((tuple, j) =>
|
{line.map((tuple, j) =>
|
||||||
<span key={`tuple${j}`} className={tuple[0]}>
|
<span key={`tuple${j}`} className={tuple[0]}>
|
||||||
@ -48,11 +71,21 @@ function ViewServer(props){
|
|||||||
)}
|
)}
|
||||||
</pre>
|
</pre>
|
||||||
{ViewImage.matches(message) &&
|
{ViewImage.matches(message) &&
|
||||||
<ViewImage {...props} />
|
<ViewImage {...this.props} />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewServer = ContentLoader(ViewServer)
|
ViewServer = connect(
|
||||||
|
state => ({
|
||||||
|
showFullContent: state.ui.flow.showFullContent
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
setContentViewDescription,
|
||||||
|
setShowFullContent
|
||||||
|
}
|
||||||
|
)(ContentLoader(ViewServer))
|
||||||
|
|
||||||
export { Edit, ViewServer, ViewImage }
|
export { Edit, ViewServer, ViewImage }
|
||||||
|
29
web/src/js/components/ContentView/ShowFullContentButton.jsx
Normal file
29
web/src/js/components/ContentView/ShowFullContentButton.jsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import React, { Component, PropTypes } from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { render } from 'react-dom';
|
||||||
|
import Button from '../common/Button';
|
||||||
|
import { setShowFullContent } from '../../ducks/ui/flow'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ShowFullContentButton.propTypes = {
|
||||||
|
setShowFullContent: PropTypes.func.isRequired,
|
||||||
|
showFullContent: PropTypes.bool.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
function ShowFullContentButton ( {setShowFullContent, showFullContent} ){
|
||||||
|
|
||||||
|
return (
|
||||||
|
!showFullContent && <Button isXs={true} onClick={() => setShowFullContent(true)} text="Show full content"/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
state => ({
|
||||||
|
showFullContent: state.ui.flow.showFullContent
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
setShowFullContent
|
||||||
|
}
|
||||||
|
)(ShowFullContentButton)
|
||||||
|
|
@ -1,48 +1,82 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes, Component } from 'react'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import * as ContentViews from './ContentViews'
|
import * as ContentViews from './ContentViews'
|
||||||
import { setContentView } from "../../ducks/ui/flow";
|
import { setContentView, setContentViewSelectorOpen } from "../../ducks/ui/flow";
|
||||||
|
|
||||||
|
|
||||||
function ViewButton({ name, setContentView, children, activeView }) {
|
function ViewItem({ name, setContentView, children }) {
|
||||||
return (
|
return (
|
||||||
<button
|
<li>
|
||||||
onClick={() => setContentView(name)}
|
<a href="#" onClick={() => setContentView(name)}>
|
||||||
className={classnames('btn btn-default', { active: name === activeView })}>
|
|
||||||
{children}
|
{children}
|
||||||
</button>
|
</a>
|
||||||
|
</li>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ViewButton = connect(state => ({
|
|
||||||
activeView: state.ui.flow.contentView
|
|
||||||
}), {
|
|
||||||
setContentView
|
|
||||||
})(ViewButton)
|
|
||||||
|
|
||||||
|
|
||||||
ViewSelector.propTypes = {
|
/*ViewSelector.propTypes = {
|
||||||
message: PropTypes.object.isRequired,
|
contentViews: PropTypes.array.isRequired,
|
||||||
}
|
activeView: PropTypes.string.isRequired,
|
||||||
function ViewSelector({contentViews, isEdit }) {
|
isEdit: PropTypes.bool.isRequired,
|
||||||
let edit = ContentViews.Edit.displayName
|
isContentViewSelectorOpen: PropTypes.bool.isRequired,
|
||||||
return (
|
setContentViewSelectorOpen: PropTypes.func.isRequired
|
||||||
<div className="view-selector btn-group btn-group-xs">
|
}*/
|
||||||
|
|
||||||
{contentViews.map(name =>
|
|
||||||
<ViewButton key={name} name={name}>{name.toLowerCase().replace('_', ' ')}</ViewButton>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{isEdit &&
|
class ViewSelector extends Component {
|
||||||
<ViewButton key={edit} name={edit}>{edit.toLowerCase()}</ViewButton>
|
constructor(props, context) {
|
||||||
|
super(props, context)
|
||||||
|
this.close = this.close.bind(this)
|
||||||
|
}
|
||||||
|
close() {
|
||||||
|
this.props.setContentViewSelectorOpen(false)
|
||||||
|
document.removeEventListener('click', this.close)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDropdown(e){
|
||||||
|
e.preventDefault()
|
||||||
|
this.props.setContentViewSelectorOpen(!this.props.isContentViewSelectorOpen)
|
||||||
|
document.addEventListener('click', this.close)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {contentViews, activeView, isEdit, isContentViewSelectorOpen, setContentViewSelectorOpen, setContentView} = this.props
|
||||||
|
let edit = ContentViews.Edit.displayName
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classnames('dropup pull-left', { open: isContentViewSelectorOpen })}>
|
||||||
|
<a className="btn btn-default btn-xs"
|
||||||
|
onClick={ e => this.onDropdown(e) }
|
||||||
|
href="#">
|
||||||
|
<b>View:</b> {activeView}<span className="caret"></span>
|
||||||
|
</a>
|
||||||
|
<ul className="dropdown-menu" role="menu">
|
||||||
|
{contentViews.map(name =>
|
||||||
|
<ViewItem key={name} setContentView={setContentView} name={name}>
|
||||||
|
{name.toLowerCase().replace('_', ' ')}
|
||||||
|
</ViewItem>
|
||||||
|
)}
|
||||||
|
{isEdit &&
|
||||||
|
<ViewItem key={edit} setContentView={setContentView} name={edit}>
|
||||||
|
{edit.toLowerCase()}
|
||||||
|
</ViewItem>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect (
|
export default connect (
|
||||||
state => ({
|
state => ({
|
||||||
contentViews: state.settings.contentViews,
|
contentViews: state.settings.contentViews,
|
||||||
|
activeView: state.ui.flow.contentView,
|
||||||
isEdit: !!state.ui.flow.modifiedFlow,
|
isEdit: !!state.ui.flow.modifiedFlow,
|
||||||
}))(ViewSelector)
|
isContentViewSelectorOpen: state.ui.flow.isContentViewSelectorOpen
|
||||||
|
}), {
|
||||||
|
setContentView,
|
||||||
|
setContentViewSelectorOpen
|
||||||
|
}
|
||||||
|
)(ViewSelector)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from 'react'
|
||||||
|
import classnames from 'classnames'
|
||||||
|
|
||||||
Button.propTypes = {
|
Button.propTypes = {
|
||||||
onClick: PropTypes.func.isRequired,
|
onClick: PropTypes.func.isRequired,
|
||||||
@ -6,9 +7,9 @@ Button.propTypes = {
|
|||||||
icon: PropTypes.string
|
icon: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Button({ onClick, text, icon, disabled }) {
|
export default function Button({ onClick, text, icon, disabled, isXs }) {
|
||||||
return (
|
return (
|
||||||
<div className={"btn btn-default"}
|
<div className={classnames('btn btn-default', { 'btn-xs': isXs})}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
disabled={disabled}>
|
disabled={disabled}>
|
||||||
{icon && (<i className={"fa fa-fw " + icon}/> )}
|
{icon && (<i className={"fa fa-fw " + icon}/> )}
|
||||||
|
@ -8,11 +8,17 @@ export const SET_CONTENT_VIEW = 'UI_FLOWVIEW_SET_CONTENT_VIEW',
|
|||||||
SET_TAB = "UI_FLOWVIEW_SET_TAB",
|
SET_TAB = "UI_FLOWVIEW_SET_TAB",
|
||||||
START_EDIT = 'UI_FLOWVIEW_START_EDIT',
|
START_EDIT = 'UI_FLOWVIEW_START_EDIT',
|
||||||
UPDATE_EDIT = 'UI_FLOWVIEW_UPDATE_EDIT',
|
UPDATE_EDIT = 'UI_FLOWVIEW_UPDATE_EDIT',
|
||||||
UPLOAD_CONTENT = 'UI_FLOWVIEW_UPLOAD_CONTENT'
|
UPLOAD_CONTENT = 'UI_FLOWVIEW_UPLOAD_CONTENT',
|
||||||
|
SET_SHOW_FULL_CONTENT = 'UI_SET_SHOW_FULL_CONTENT',
|
||||||
|
SET_CONTENT_VIEW_DESCRIPTION = "UI_SET_CONTENT_VIEW_DESCRIPTION",
|
||||||
|
SET_CONTENT_VIEW_SELECTOR = "UI_SET_CONTENT_VIEW_SELECTOR"
|
||||||
|
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
displayLarge: false,
|
displayLarge: false,
|
||||||
|
contentViewDescription: '',
|
||||||
|
showFullContent: false,
|
||||||
|
isContentViewSelectorOpen: false,
|
||||||
modifiedFlow: false,
|
modifiedFlow: false,
|
||||||
contentView: 'Auto',
|
contentView: 'Auto',
|
||||||
tab: 'request',
|
tab: 'request',
|
||||||
@ -26,7 +32,8 @@ export default function reducer(state = defaultState, action) {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
modifiedFlow: action.flow,
|
modifiedFlow: action.flow,
|
||||||
contentView: 'Edit'
|
contentView: 'Edit',
|
||||||
|
showFullContent: true
|
||||||
}
|
}
|
||||||
|
|
||||||
case UPDATE_EDIT:
|
case UPDATE_EDIT:
|
||||||
@ -40,7 +47,9 @@ export default function reducer(state = defaultState, action) {
|
|||||||
...state,
|
...state,
|
||||||
modifiedFlow: false,
|
modifiedFlow: false,
|
||||||
displayLarge: false,
|
displayLarge: false,
|
||||||
contentView: (wasInEditMode ? 'Auto' : state.contentView)
|
contentView: (wasInEditMode ? 'Auto' : state.contentView),
|
||||||
|
viewDescription: '',
|
||||||
|
showFullContent: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
case flowsActions.UPDATE:
|
case flowsActions.UPDATE:
|
||||||
@ -52,24 +61,46 @@ export default function reducer(state = defaultState, action) {
|
|||||||
...state,
|
...state,
|
||||||
modifiedFlow: false,
|
modifiedFlow: false,
|
||||||
displayLarge: false,
|
displayLarge: false,
|
||||||
contentView: (wasInEditMode ? 'Auto' : state.contentView)
|
contentView: (wasInEditMode ? 'Auto' : state.contentView),
|
||||||
|
viewDescription: '',
|
||||||
|
showFullContent: false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SET_CONTENT_VIEW_DESCRIPTION:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
viewDescription: action.description
|
||||||
|
}
|
||||||
|
|
||||||
|
case SET_SHOW_FULL_CONTENT:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
showFullContent: action.show
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case SET_CONTENT_VIEW_SELECTOR:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isContentViewSelectorOpen: action.contentViewSelector
|
||||||
|
}
|
||||||
|
|
||||||
case SET_TAB:
|
case SET_TAB:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
tab: action.tab,
|
tab: action.tab,
|
||||||
displayLarge: false,
|
displayLarge: false,
|
||||||
|
showFullContent: false
|
||||||
}
|
}
|
||||||
|
|
||||||
case SET_CONTENT_VIEW:
|
case SET_CONTENT_VIEW:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
contentView: action.contentView,
|
contentView: action.contentView,
|
||||||
|
showFullContent: action.contentView == 'Edit'
|
||||||
}
|
}
|
||||||
|
|
||||||
case DISPLAY_LARGE:
|
case DISPLAY_LARGE:
|
||||||
@ -102,6 +133,22 @@ export function updateEdit(update) {
|
|||||||
return { type: UPDATE_EDIT, update }
|
return { type: UPDATE_EDIT, update }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setContentViewDescription(description) {
|
||||||
|
return { type: SET_CONTENT_VIEW_DESCRIPTION, description }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setShowFullContent(show) {
|
||||||
|
return { type: SET_SHOW_FULL_CONTENT, show }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setContentViewSelectorOpen(open){
|
||||||
|
return {type: SET_CONTENT_VIEW_SELECTOR, contentViewSelector: open}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateEdit(update) {
|
||||||
|
return { type: UPDATE_EDIT, update }
|
||||||
|
}
|
||||||
|
|
||||||
export function stopEdit(flow, modifiedFlow) {
|
export function stopEdit(flow, modifiedFlow) {
|
||||||
let diff = getDiff(flow, modifiedFlow)
|
let diff = getDiff(flow, modifiedFlow)
|
||||||
return flowsActions.update(flow, diff)
|
return flowsActions.update(flow, diff)
|
||||||
|
Loading…
Reference in New Issue
Block a user