Update callbacks requst section

Add one more dropdown
This commit is contained in:
Oleksiy Kachynskyy 2020-03-31 22:57:44 +03:00
parent 4f49b28d84
commit 7b6ca9bda1
6 changed files with 152 additions and 54 deletions

View File

@ -0,0 +1,31 @@
import * as React from 'react';
import { DropdownProps } from '../../common-elements';
import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
import { OperationModel } from '../../services/models';
import { XPayloadSample } from '../../services/models/Operation';
import { isPayloadSample } from '../../services';
import { ReqSamplesWrapper } from './styled.elements';
export interface PayloadSamplesProps {
callback: OperationModel;
renderDropdown: (props: DropdownProps) => JSX.Element;
}
export class CallbackReqSamples extends React.Component<PayloadSamplesProps> {
render() {
const payloadSample = this.props.callback.codeSamples.find(sample =>
isPayloadSample(sample),
) as XPayloadSample | undefined;
return (
<>
{payloadSample ? (
<ReqSamplesWrapper>
<PayloadSamples content={payloadSample.requestBodyContent} />
</ReqSamplesWrapper>
) : null}
</>
);
}
}

View File

@ -1,12 +1,15 @@
import { observer } from 'mobx-react';
import * as React from 'react';
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
import { isPayloadSample, RedocNormalizedOptions } from '../../services';
import { RightPanelHeader } from '../../common-elements';
import { RedocNormalizedOptions } from '../../services';
import { CallbackModel } from '../../services/models';
import { OptionsContext } from '../OptionsProvider';
import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
import { SourceCodeWithCopy } from '../SourceCode/SourceCode';
import { CallbacksSwitch } from '../CallbacksSwitch/CallbacksSwitch';
import { DropdownOrLabel } from '../DropdownOrLabel/DropdownOrLabel';
import { InvertedSimpleDropdown, MimeLabel } from '../PayloadSamples/styled.elements';
import { CallbackReqSamples } from './CallbackReqSamples';
import { SamplesWrapper } from './styled.elements';
export interface CallbackSamplesProps {
callbacks: CallbackModel[];
@ -17,66 +20,45 @@ export class CallbackSamples extends React.Component<CallbackSamplesProps> {
static contextType = OptionsContext;
context: RedocNormalizedOptions;
private renderDropdown = props => {
return <DropdownOrLabel Label={MimeLabel} Dropdown={InvertedSimpleDropdown} {...props} />;
};
render() {
const { callbacks } = this.props;
const operations = callbacks
.map(callback => callback.operations.map(operation => operation))
.reduce((a, b) => a.concat(b), []);
// Sums number of code samples per operation per callback
const numSamples = callbacks.reduce(
(callbackSum, callback) =>
callbackSum +
callback.operations.reduce(
const numSamples = operations.reduce(
(sampleSum, operation) => sampleSum + operation.codeSamples.length,
0,
),
0,
);
const hasSamples = numSamples > 0;
const hideTabList = numSamples === 1 ? this.context.hideSingleRequestSampleTab : false;
const renderTabs = () => {
return callbacks.map(callback => {
return callback.operations.map(operation => {
return operation.codeSamples.map(sample => {
return (
<Tab key={operation.id + '_' + operation.name}>
{operation.name} {sample.label !== undefined ? sample.label : sample.lang}
</Tab>
);
});
});
});
};
const renderTabPanels = () => {
return callbacks.map(callback => {
return callback.operations.map(operation => {
return operation.codeSamples.map(sample => {
return (
<TabPanel key={sample.lang + '_' + (sample.label || '')}>
{isPayloadSample(sample) ? (
<div>
<PayloadSamples content={sample.requestBodyContent} />
</div>
) : (
<SourceCodeWithCopy lang={sample.lang} source={sample.source} />
)}
</TabPanel>
);
});
});
});
};
return (
(hasSamples && (
<div>
<RightPanelHeader> Callback samples </RightPanelHeader>
<RightPanelHeader> Callback request samples </RightPanelHeader>
<Tabs defaultIndex={0}>
<TabList hidden={hideTabList}>{renderTabs()}</TabList>
{renderTabPanels()}
</Tabs>
<SamplesWrapper>
<CallbacksSwitch
callbacks={operations}
renderDropdown={this.renderDropdown}
withLabel={true}
>
{callback => (
<CallbackReqSamples
key="callbackReqSamples"
callback={callback}
renderDropdown={this.renderDropdown}
/>
)}
</CallbacksSwitch>
</SamplesWrapper>
</div>
)) ||
null

View File

@ -0,0 +1,10 @@
import styled from '../../styled-components';
export const SamplesWrapper = styled.div`
background: ${({ theme }) => theme.codeSample.backgroundColor};
padding: ${props => props.theme.spacing.unit * 4}px;
`;
export const ReqSamplesWrapper = styled.div`
margin-top: 15px;
`;

View File

@ -28,8 +28,8 @@ export class CallbacksList extends React.PureComponent<CallbacksListProps> {
<div>
<CallbacksHeader> Callbacks </CallbacksHeader>
{callbacks.map(callback => {
return callback.operations.map(operation => {
return <CallbackView key={callback.name} callbackOperation={operation} />;
return callback.operations.map((operation, index) => {
return <CallbackView key={callback.name + index} callbackOperation={operation} />;
});
})}
</div>

View File

@ -0,0 +1,75 @@
import { observer } from 'mobx-react';
import * as React from 'react';
import { DropdownProps } from '../../common-elements/dropdown';
import { DropdownLabel, DropdownWrapper } from '../PayloadSamples/styled.elements';
import { OperationModel } from '../../services/models';
export interface CallbacksSwitchProps {
callbacks?: OperationModel[];
withLabel?: boolean;
renderDropdown: (props: DropdownProps) => JSX.Element;
children: (activeCallback: OperationModel) => JSX.Element;
}
export interface CallbacksSwitchState {
activeItemIdx: number;
}
@observer
export class CallbacksSwitch extends React.Component<CallbacksSwitchProps, CallbacksSwitchState> {
constructor(props) {
super(props);
this.state = {
activeItemIdx: 0,
};
}
switchCallback = ({ value }) => {
if (this.props.callbacks) {
this.setState({
activeItemIdx: parseInt(value, 10),
});
}
};
render() {
const { callbacks } = this.props;
if (!callbacks || !callbacks.length) {
return null;
}
const options = callbacks.map((callback, idx) => {
return {
label: `[${callback.httpVerb.toUpperCase()}] ${callback.name}`,
value: idx.toString(),
};
});
const Wrapper = ({ children }) =>
this.props.withLabel ? (
<DropdownWrapper>
<DropdownLabel>Callback</DropdownLabel>
{children}
</DropdownWrapper>
) : (
children
);
return (
<>
<Wrapper>
{this.props.renderDropdown({
value: options[this.state.activeItemIdx],
options,
onChange: this.switchCallback,
})}
</Wrapper>
{this.props.children(callbacks[this.state.activeItemIdx])}
</>
);
}
}

View File

@ -32,7 +32,7 @@ import { MediaContentModel } from './MediaContent';
import { RequestBodyModel } from './RequestBody';
import { ResponseModel } from './Response';
interface XPayloadSample {
export interface XPayloadSample {
lang: 'payload';
label: string;
requestBodyContent: MediaContentModel;