diff --git a/src/components/Console/ConsoleViewer.tsx b/src/components/Console/ConsoleViewer.tsx index f21cb5c6..5a8c3b94 100644 --- a/src/components/Console/ConsoleViewer.tsx +++ b/src/components/Console/ConsoleViewer.tsx @@ -4,6 +4,7 @@ import { SecuritySchemeModel } from '../../../typings/services/models'; import { SubmitButton } from '../../common-elements/buttons'; import { FlexLayoutReverse } from '../../common-elements/panels'; import { FieldModel, OperationModel, SecuritySchemesModel } from '../../services/models'; +import { ConsoleResponse } from '../ConsoleResponse/Response'; import { SourceCodeWithCopy } from '../SourceCode/SourceCode'; import { ConsoleEditor } from './ConsoleEditor'; @@ -15,6 +16,7 @@ export interface ConsoleViewerProps { queryParamPrefix?: string; queryParamSuffix?: string; securitySchemes: SecuritySchemesModel; + urlIndex: number; } export interface ConsoleViewerState { @@ -40,7 +42,7 @@ export class ConsoleViewer extends React.Component { const ace = this.consoleEditor && this.consoleEditor.editor; - const { operation, securitySchemes: {schemes}, additionalHeaders = {} } = this.props; + const { operation, securitySchemes: {schemes}, additionalHeaders = {}, urlIndex = 0 } = this.props; let value = ace && ace.editor.getValue(); @@ -48,7 +50,7 @@ export class ConsoleViewer extends React.ComponentSend Request {result && - + } ); diff --git a/src/components/ConsoleResponse/Response.tsx b/src/components/ConsoleResponse/Response.tsx new file mode 100644 index 00000000..ddc5031f --- /dev/null +++ b/src/components/ConsoleResponse/Response.tsx @@ -0,0 +1,114 @@ +import * as React from 'react'; +import { SourceCodeWithCopy } from '..'; +import { RightPanelHeader } from '../../common-elements'; +import styled from '../../styled-components'; + +import { JsonViewer } from '../JsonViewer/JsonViewer'; + +interface ConsoleResponseProps { + response: any; +} + +interface ConsoleResponseState { + collapse: boolean; +} + +export class ConsoleResponse extends React.PureComponent { + + constructor(props) { + super(props); + this.state = { collapse: false}; + } + + changeCollapse = () => { + this.setState({collapse: !this.state.collapse}); + }; + + render() { + return( + <> + status: + {this.props.response.status} {this.props.response.statusText} + Response Payload + + + + Response Headers + + + + + + + show undocumented response headers + + + + ); + } +} + +const HeaderWrapper = styled.div` + color: white; + background-color: ${props => props.theme.codeSample.backgroundColor}; + padding: 10px 0 18px; + margin: 10px 0; + height: 100%; + div div div { + display: none !important; + } + div pre span:first-child { + display: none !important; + } + div pre span:last-child { + display: none !important; + } + div pre { + height: 100%; + overflow: hidden; + } + div { + height: 100%; + } +`; + +const SourceCodeWrapper = styled.div` + &.collapse-false { + height: 89px; + } + &.collapse-true { + height: auto; + } +`; + +const JsonWrapper = styled.div` + color: white; + background-color: ${props => props.theme.codeSample.backgroundColor}; + padding: 10px; + margin: 10px 0; +`; + +const StatusWrapper = styled.div` + &.status-success { + color: #00ff1c; + } + &.status-redirect { + color: ${props => props.theme.colors.responses.redirect.color}; + } + &.status-info { + color: ${props => props.theme.colors.responses.info.color}; + } + &.status-error { + color: ${props => props.theme.colors.responses.error.color}; + } + color: white; + background-color: ${props => props.theme.codeSample.backgroundColor}; + padding: 10px; + margin: 10px 0; +`; + +const ShowMore = styled.div` + text-align: center; + u { + cursor: pointer; + } +`; diff --git a/src/components/Endpoint/Endpoint.tsx b/src/components/Endpoint/Endpoint.tsx index 280a8582..6b251507 100644 --- a/src/components/Endpoint/Endpoint.tsx +++ b/src/components/Endpoint/Endpoint.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { ShelfIcon } from '../../common-elements'; -import { OperationModel } from '../../services'; +import { ClipboardService, OperationModel } from '../../services'; import { Markdown } from '../Markdown/Markdown'; import { OptionsContext } from '../OptionsProvider'; import { SelectOnClick } from '../SelectOnClick/SelectOnClick'; @@ -21,10 +21,13 @@ export interface EndpointProps { hideHostname?: boolean; inverted?: boolean; + handleUrl: any; } export interface EndpointState { expanded: boolean; + selectedItem: number; + tooltipShown: boolean; } export class Endpoint extends React.Component { @@ -32,6 +35,8 @@ export class Endpoint extends React.Component { super(props); this.state = { expanded: false, + selectedItem: 0, + tooltipShown: false, }; } @@ -48,6 +53,9 @@ export class Endpoint extends React.Component { {options => ( +
+ Copied +
{operation.httpVerb}{' '} {operation.path} @@ -60,14 +68,14 @@ export class Endpoint extends React.Component { /> - {operation.servers.map(server => { + {operation.servers.map((server, index) => { const normalizedUrl = options.expandDefaultServerVariables ? expandDefaultServerVariables(server.url, server.variables) : server.url; return ( - - - + + + {hideHostname || options.hideHostname @@ -86,4 +94,19 @@ export class Endpoint extends React.Component {
); } + + handleUrl(url: number) { + this.props.handleUrl(url); + this.setState({ + selectedItem: url, + expanded: false, + tooltipShown: true, + }); + ClipboardService.copyCustom(this.props.operation.servers[url].url + this.props.operation.path); + setTimeout(() => { + this.setState({ + tooltipShown: false, + }); + }, 1000); + } } diff --git a/src/components/Endpoint/styled.elements.ts b/src/components/Endpoint/styled.elements.ts index 853f38b1..9913d842 100644 --- a/src/components/Endpoint/styled.elements.ts +++ b/src/components/Endpoint/styled.elements.ts @@ -4,6 +4,26 @@ export const OperationEndpointWrap = styled.div` cursor: pointer; position: relative; margin-bottom: 5px; + .showToolTip { + visibility: initial; + background-color: white; + color: black; + padding: 3px; + position: initial; + width: 53px; + text-align: center; + margin-bottom: 10px; + border-radius: 4px; + }; + .hideToolTip { + visibility:hidden; + padding: 3px; + position: initial; + width: 53px; + text-align: center; + margin-bottom: 10px; + border-radius: 4px; + } `; export const ServerRelativeURL = styled.span` @@ -66,16 +86,28 @@ export const ServersOverlay = styled.div<{ expanded: boolean }>` export const ServerItem = styled.div` padding: 10px; + background-color: #002c2d; + color: white; + display: flex; + flex-wrap: nowrap; + &.selected { + background-color: #3c7173; + } + div:first-child { + width: 20%; + padding-top: 5px; + } `; export const ServerUrl = styled.div` text-align: left; - padding: 5px; - border: 1px solid #ccc; - background: #fff; + user-select: none; + padding: 5px !important; + background-color: #ffffff33; word-break: break-all; - color: ${props => props.theme.colors.primary.main}; + width: 100% !important; + color: #00ff1c; > span { - color: ${props => props.theme.colors.text.primary}; + color: white; }; `; diff --git a/src/components/Markdown/Markdown.tsx b/src/components/Markdown/Markdown.tsx index 544a2bc8..ec3443ef 100644 --- a/src/components/Markdown/Markdown.tsx +++ b/src/components/Markdown/Markdown.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { MarkdownRenderer } from '../../services'; +import styled from '../../styled-components'; import { SanitizedMarkdownHTML } from './SanitizedMdBlock'; export interface StylingMarkdownProps { @@ -17,19 +18,31 @@ export type MarkdownProps = BaseMarkdownProps & StylingMarkdownProps & { source: string; className?: string; + onSelectUrl?: any; }; export class Markdown extends React.Component { + handleClick = () => { + this.props.onSelectUrl(); + }; render() { const { source, inline, compact, className } = this.props; const renderer = new MarkdownRenderer(); return ( - + + + ); } } +const MarkWrapper = styled.div` + div { + width: 100% !important; + padding-top: 0 !important; + } +`; diff --git a/src/components/Operation/Operation.tsx b/src/components/Operation/Operation.tsx index d9883c92..2e634bc3 100644 --- a/src/components/Operation/Operation.tsx +++ b/src/components/Operation/Operation.tsx @@ -39,6 +39,7 @@ export interface OperationProps { export interface OperationState { executeMode: boolean; + urlIndex: number; } @observer @@ -48,6 +49,7 @@ export class Operation extends React.Component { super(props); this.state = { executeMode: false, + urlIndex: 0, }; } @@ -59,7 +61,7 @@ export class Operation extends React.Component { render() { const { operation, securitySchemes } = this.props; - const { executeMode } = this.state; + const { executeMode, urlIndex } = this.state; const { name: summary, description, deprecated, externalDocs } = operation; const hasDescription = !!(description || externalDocs); @@ -80,7 +82,7 @@ export class Operation extends React.Component { label="Try it out!" /> } - {options.pathInMiddlePanel && } + {options.pathInMiddlePanel && } {hasDescription && ( {description !== undefined && } @@ -93,12 +95,13 @@ export class Operation extends React.Component { - {!options.pathInMiddlePanel && } + {!options.pathInMiddlePanel && } {executeMode &&
{ ); } + onUrlChanged = (index= 0) => { + this.setState({ + urlIndex: index, + }); + } } diff --git a/src/components/SelectOnClick/SelectOnClick.tsx b/src/components/SelectOnClick/SelectOnClick.tsx index 9856905c..0f3b879b 100644 --- a/src/components/SelectOnClick/SelectOnClick.tsx +++ b/src/components/SelectOnClick/SelectOnClick.tsx @@ -1,19 +1,28 @@ import * as React from 'react'; import { ClipboardService } from '../../services'; +import styled from '../../styled-components'; -export class SelectOnClick extends React.PureComponent { +interface SelectOnClickProps { + onSelectUrl: () => void; +} + +export class SelectOnClick extends React.PureComponent { private child: HTMLDivElement | null; handleClick = () => { ClipboardService.selectElement(this.child); + this.props.onSelectUrl(); }; render() { const { children } = this.props; return ( -
(this.child = el)} onClick={this.handleClick}> + (this.child = el)} onClick={this.handleClick.bind(this, children)}> {children} -
+ ); } } +const SelectArea = styled.div` + width: 80%; +`;