Merge pull request #421 from 0xProject/moveOutDocGenerator

Docs Refactor Prepping For Moving To Separate Package
This commit is contained in:
Fabio Berger
2018-02-27 15:49:58 -08:00
committed by GitHub
15 changed files with 317 additions and 252 deletions

View File

@@ -319,7 +319,6 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
shouldDisplaySectionHeaders={false}
onMenuItemClick={this._onMenuButtonClick.bind(this)}
selectedVersion={this.props.docsVersion}
docPath={this.props.docsInfo.websitePath}
versions={this.props.availableDocVersions}
/>
</div>

View File

@@ -2,15 +2,14 @@ import * as _ from 'lodash';
import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page';
import { DocsInfo } from 'ts/pages/documentation/docs_info';
import { Documentation as DocumentationComponent, DocumentationAllProps } from 'ts/pages/documentation/documentation';
import { Dispatcher } from 'ts/redux/dispatcher';
import { State } from 'ts/redux/reducer';
import { DocsInfoConfig, Environments, WebsitePaths } from 'ts/types';
import { DocPackages, DocsInfoConfig, Environments, SupportedDocJson, WebsitePaths } from 'ts/types';
import { configs } from 'ts/utils/configs';
import { constants } from 'ts/utils/constants';
import { Translate } from 'ts/utils/translate';
import { typeDocUtils } from 'ts/utils/typedoc_utils';
/* tslint:disable:no-var-requires */
const IntroMarkdown = require('md/docs/connect/introduction');
@@ -25,16 +24,11 @@ const connectDocSections = {
types: constants.TYPES_SECTION_NAME,
};
const s3BucketName =
configs.ENVIRONMENT === Environments.DEVELOPMENT ? 'staging-connect-docs-jsons' : 'connect-docs-jsons';
const docsJsonRoot = `https://s3.amazonaws.com/${s3BucketName}`;
const docsInfoConfig: DocsInfoConfig = {
id: DocPackages.Connect,
type: SupportedDocJson.TypeDoc,
displayName: '0x Connect',
subPackageName: 'connect',
packageUrl: 'https://github.com/0xProject/0x.js',
websitePath: WebsitePaths.Connect,
docsJsonRoot,
menu: {
introduction: [connectDocSections.introduction],
install: [connectDocSections.installation],
@@ -77,7 +71,6 @@ const docsInfoConfig: DocsInfoConfig = {
menuSubsectionToVersionWhenIntroduced: {},
sections: connectDocSections,
visibleConstructors: [connectDocSections.httpClient, connectDocSections.webSocketOrderbookChannel],
convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
};
const docsInfo = new DocsInfo(docsInfoConfig);
@@ -92,7 +85,7 @@ interface ConnectedDispatch {
dispatcher: Dispatcher;
}
const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({
docsVersion: state.docsVersion,
availableDocVersions: state.availableDocVersions,
translate: state.translate,
@@ -103,6 +96,6 @@ const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
dispatcher: new Dispatcher(dispatch),
});
export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
DocumentationComponent,
export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)(
DocPageComponent,
);

View File

@@ -2,12 +2,18 @@ import * as _ from 'lodash';
import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page';
import { DocsInfo } from 'ts/pages/documentation/docs_info';
import { Documentation as DocumentationComponent, DocumentationAllProps } from 'ts/pages/documentation/documentation';
import { Dispatcher } from 'ts/redux/dispatcher';
import { State } from 'ts/redux/reducer';
import { DocsInfoConfig, SmartContractDocSections as Sections, WebsitePaths } from 'ts/types';
import { doxityUtils } from 'ts/utils/doxity_utils';
import {
DocPackages,
DocsInfoConfig,
Networks,
SmartContractDocSections as Sections,
SupportedDocJson,
WebsitePaths,
} from 'ts/types';
import { Translate } from 'ts/utils/translate';
/* tslint:disable:no-var-requires */
@@ -15,10 +21,10 @@ const IntroMarkdown = require('md/docs/smart_contracts/introduction');
/* tslint:enable:no-var-requires */
const docsInfoConfig: DocsInfoConfig = {
id: DocPackages.SmartContracts,
type: SupportedDocJson.Doxity,
displayName: '0x Smart Contracts',
packageUrl: 'https://github.com/0xProject/contracts',
websitePath: WebsitePaths.SmartContracts,
docsJsonRoot: 'https://s3.amazonaws.com/smart-contracts-docs-json',
menu: {
introduction: [Sections.Introduction],
contracts: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
@@ -34,7 +40,34 @@ const docsInfoConfig: DocsInfoConfig = {
ZRXToken: Sections.ZRXToken,
},
visibleConstructors: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
convertToDocAgnosticFormatFn: doxityUtils.convertToDocAgnosticFormat.bind(doxityUtils),
contractsByVersionByNetworkId: {
'1.0.0': {
[Networks.Mainnet]: {
[Sections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
[Sections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
[Sections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
[Sections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
},
[Networks.Ropsten]: {
[Sections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
[Sections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
[Sections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
[Sections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
},
[Networks.Kovan]: {
[Sections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
[Sections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
[Sections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
[Sections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
},
[Networks.Rinkeby]: {
[Sections.Exchange]: '0x1d16ef40fac01cec8adac2ac49427b9384192c05',
[Sections.TokenTransferProxy]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
[Sections.ZRXToken]: '0x00f58d6d585f84b2d7267940cede30ce2fe6eae8',
[Sections.TokenRegistry]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
},
},
},
};
const docsInfo = new DocsInfo(docsInfoConfig);
@@ -49,7 +82,7 @@ interface ConnectedDispatch {
docsInfo: DocsInfo;
}
const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({
docsVersion: state.docsVersion,
availableDocVersions: state.availableDocVersions,
translate: state.translate,
@@ -60,6 +93,6 @@ const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
docsInfo,
});
export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
DocumentationComponent,
export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)(
DocPageComponent,
);

View File

@@ -2,15 +2,14 @@ import * as _ from 'lodash';
import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page';
import { DocsInfo } from 'ts/pages/documentation/docs_info';
import { Documentation as DocumentationComponent, DocumentationAllProps } from 'ts/pages/documentation/documentation';
import { Dispatcher } from 'ts/redux/dispatcher';
import { State } from 'ts/redux/reducer';
import { DocsInfoConfig, Environments, WebsitePaths } from 'ts/types';
import { DocPackages, DocsInfoConfig, Environments, SupportedDocJson, WebsitePaths } from 'ts/types';
import { configs } from 'ts/utils/configs';
import { constants } from 'ts/utils/constants';
import { Translate } from 'ts/utils/translate';
import { typeDocUtils } from 'ts/utils/typedoc_utils';
/* tslint:disable:no-var-requires */
const IntroMarkdown = require('md/docs/0xjs/introduction');
@@ -37,15 +36,11 @@ const zeroExJsDocSections = {
types: constants.TYPES_SECTION_NAME,
};
const s3BucketName = configs.ENVIRONMENT === Environments.DEVELOPMENT ? 'staging-0xjs-docs-jsons' : '0xjs-docs-jsons';
const docsJsonRoot = `https://s3.amazonaws.com/${s3BucketName}`;
const docsInfoConfig: DocsInfoConfig = {
id: DocPackages.ZeroExJs,
type: SupportedDocJson.TypeDoc,
displayName: '0x.js',
packageUrl: 'https://github.com/0xProject/0x.js',
subPackageName: '0x.js',
websitePath: WebsitePaths.ZeroExJs,
docsJsonRoot,
menu: {
introduction: [zeroExJsDocSections.introduction],
install: [zeroExJsDocSections.installation],
@@ -69,7 +64,8 @@ const docsInfoConfig: DocsInfoConfig = {
[zeroExJsDocSections.versioning]: versioningMarkdown,
},
// Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
// currently no way to extract the re-exported types from index.ts via TypeDoc :(
// currently no way to extract the re-exported types from index.ts via TypeDoc :( Make sure to only
// ADD types here, DO NOT REMOVE types since they might still be needed for older supported versions
publicTypes: [
'Order',
'SignedOrder',
@@ -147,7 +143,6 @@ const docsInfoConfig: DocsInfoConfig = {
},
sections: zeroExJsDocSections,
visibleConstructors: [zeroExJsDocSections.zeroEx],
convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
};
const docsInfo = new DocsInfo(docsInfoConfig);
@@ -162,7 +157,7 @@ interface ConnectedDispatch {
dispatcher: Dispatcher;
}
const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({
docsVersion: state.docsVersion,
availableDocVersions: state.availableDocVersions,
docsInfo,
@@ -173,6 +168,6 @@ const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
dispatcher: new Dispatcher(dispatch),
});
export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
DocumentationComponent,
export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)(
DocPageComponent,
);

View File

@@ -0,0 +1,132 @@
import findVersions = require('find-versions');
import * as _ from 'lodash';
import * as React from 'react';
import DocumentTitle = require('react-document-title');
import semverSort = require('semver-sort');
import { TopBar } from 'ts/components/top_bar/top_bar';
import { DocsInfo } from 'ts/pages/documentation/docs_info';
import { Documentation } from 'ts/pages/documentation/documentation';
import { Dispatcher } from 'ts/redux/dispatcher';
import { DocAgnosticFormat, DocPackages, DoxityDocObj, Environments, MenuSubsectionsBySection } from 'ts/types';
import { configs } from 'ts/utils/configs';
import { constants } from 'ts/utils/constants';
import { docUtils } from 'ts/utils/doc_utils';
import { Translate } from 'ts/utils/translate';
const docIdToS3BucketName: { [id: string]: string } = {
[DocPackages.ZeroExJs]: '0xjs-docs-jsons',
[DocPackages.SmartContracts]: 'smart-contracts-docs-json',
[DocPackages.Connect]:
configs.ENVIRONMENT === Environments.DEVELOPMENT ? 'staging-connect-docs-jsons' : 'connect-docs-jsons',
};
const docIdToSubpackageName: { [id: string]: string } = {
[DocPackages.ZeroExJs]: '0x.js',
[DocPackages.Connect]: 'connect',
[DocPackages.SmartContracts]: 'contracts',
};
export interface DocPageProps {
location: Location;
dispatcher: Dispatcher;
docsVersion: string;
availableDocVersions: string[];
docsInfo: DocsInfo;
translate: Translate;
}
interface DocPageState {
docAgnosticFormat?: DocAgnosticFormat;
}
export class DocPage extends React.Component<DocPageProps, DocPageState> {
private _isUnmounted: boolean;
constructor(props: DocPageProps) {
super(props);
this._isUnmounted = false;
this.state = {
docAgnosticFormat: undefined,
};
}
public componentWillMount() {
const pathName = this.props.location.pathname;
const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
const versions = findVersions(lastSegment);
const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
// tslint:disable-next-line:no-floating-promises
this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
}
public componentWillUnmount() {
this._isUnmounted = true;
}
public render() {
const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
? {}
: this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
const sourceUrl = this._getSourceUrl();
return (
<div>
<DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
<TopBar
blockchainIsLoaded={false}
location={this.props.location}
docsVersion={this.props.docsVersion}
availableDocVersions={this.props.availableDocVersions}
menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
menuSubsectionsBySection={menuSubsectionsBySection}
docsInfo={this.props.docsInfo}
translate={this.props.translate}
/>
<Documentation
location={this.props.location}
docsVersion={this.props.docsVersion}
availableDocVersions={this.props.availableDocVersions}
docsInfo={this.props.docsInfo}
docAgnosticFormat={this.state.docAgnosticFormat}
menuSubsectionsBySection={menuSubsectionsBySection}
sourceUrl={sourceUrl}
/>
</div>
);
}
private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
const s3BucketName = docIdToS3BucketName[this.props.docsInfo.id];
const docsJsonRoot = `${constants.S3_BUCKET_ROOT}/${s3BucketName}`;
const versionToFileName = await docUtils.getVersionToFileNameAsync(docsJsonRoot);
const versions = _.keys(versionToFileName);
this.props.dispatcher.updateAvailableDocVersions(versions);
const sortedVersions = semverSort.desc(versions);
const latestVersion = sortedVersions[0];
let versionToFetch = latestVersion;
if (!_.isUndefined(preferredVersionIfExists)) {
const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
if (!_.isUndefined(preferredVersionFileNameIfExists)) {
versionToFetch = preferredVersionIfExists;
}
}
this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
const versionFileNameToFetch = versionToFileName[versionToFetch];
const versionDocObj = await docUtils.getJSONDocFileAsync(versionFileNameToFetch, docsJsonRoot);
const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
if (!this._isUnmounted) {
this.setState({
docAgnosticFormat,
});
}
}
private _getSourceUrl() {
const url = this.props.docsInfo.packageUrl;
const pkg = docIdToSubpackageName[this.props.docsInfo.id];
let tagPrefix = pkg;
const packagesWithNamespace = ['connect'];
if (_.includes(packagesWithNamespace, pkg)) {
tagPrefix = `@0xproject/${pkg}`;
}
const sourceUrl = `${url}/blob/${tagPrefix}%40${this.props.docsVersion}/packages/${pkg}`;
return sourceUrl;
}
}

View File

@@ -1,33 +1,37 @@
import compareVersions = require('compare-versions');
import * as _ from 'lodash';
import {
ContractsByVersionByNetworkId,
DocAgnosticFormat,
DocsInfoConfig,
DocsMenu,
DoxityDocObj,
MenuSubsectionsBySection,
SectionsMap,
SupportedDocJson,
TypeDocNode,
} from 'ts/types';
import { doxityUtils } from 'ts/utils/doxity_utils';
import { typeDocUtils } from 'ts/utils/typedoc_utils';
export class DocsInfo {
public id: string;
public type: SupportedDocJson;
public displayName: string;
public packageUrl: string;
public subPackageName?: string;
public websitePath: string;
public docsJsonRoot: string;
public menu: DocsMenu;
public sections: SectionsMap;
public sectionNameToMarkdown: { [sectionName: string]: string };
public contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
private _docsInfo: DocsInfoConfig;
constructor(config: DocsInfoConfig) {
this.id = config.id;
this.type = config.type;
this.displayName = config.displayName;
this.packageUrl = config.packageUrl;
this.subPackageName = config.subPackageName;
this.websitePath = config.websitePath;
this.docsJsonRoot = config.docsJsonRoot;
this.sections = config.sections;
this.sectionNameToMarkdown = config.sectionNameToMarkdown;
this.contractsByVersionByNetworkId = config.contractsByVersionByNetworkId;
this._docsInfo = config;
}
public isPublicType(typeName: string): boolean {
@@ -106,6 +110,10 @@ export class DocsInfo {
return _.includes(this._docsInfo.visibleConstructors, sectionName);
}
public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
return this._docsInfo.convertToDocAgnosticFormatFn(docObj, this);
if (this.type === SupportedDocJson.Doxity) {
return doxityUtils.convertToDocAgnosticFormat(docObj as DoxityDocObj);
} else {
return typeDocUtils.convertToDocAgnosticFormat(docObj as TypeDocNode, this);
}
}
}

View File

@@ -1,11 +1,7 @@
import findVersions = require('find-versions');
import * as _ from 'lodash';
import CircularProgress from 'material-ui/CircularProgress';
import * as React from 'react';
import DocumentTitle = require('react-document-title');
import { scroller } from 'react-scroll';
import semverSort = require('semver-sort');
import { TopBar } from 'ts/components/top_bar/top_bar';
import { Badge } from 'ts/components/ui/badge';
import { Comment } from 'ts/pages/documentation/comment';
import { DocsInfo } from 'ts/pages/documentation/docs_info';
@@ -17,25 +13,23 @@ import { TypeDefinition } from 'ts/pages/documentation/type_definition';
import { MarkdownSection } from 'ts/pages/shared/markdown_section';
import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu';
import { SectionHeader } from 'ts/pages/shared/section_header';
import { Dispatcher } from 'ts/redux/dispatcher';
import {
AddressByContractName,
DocAgnosticFormat,
DoxityDocObj,
EtherscanLinkSuffixes,
Event,
MenuSubsectionsBySection,
Networks,
Property,
SolidityMethod,
Styles,
SupportedDocJson,
TypeDefinitionByName,
TypescriptMethod,
} from 'ts/types';
import { colors } from 'ts/utils/colors';
import { configs } from 'ts/utils/configs';
import { constants } from 'ts/utils/constants';
import { docUtils } from 'ts/utils/doc_utils';
import { Translate } from 'ts/utils/translate';
import { utils } from 'ts/utils/utils';
const TOP_BAR_HEIGHT = 60;
@@ -48,19 +42,17 @@ const networkNameToColor: { [network: string]: string } = {
[Networks.Rinkeby]: colors.darkYellow,
};
export interface DocumentationAllProps {
source: string;
export interface DocumentationProps {
location: Location;
dispatcher: Dispatcher;
docsVersion: string;
availableDocVersions: string[];
docsInfo: DocsInfo;
translate: Translate;
docAgnosticFormat?: DocAgnosticFormat;
menuSubsectionsBySection: MenuSubsectionsBySection;
sourceUrl: string;
}
interface DocumentationState {
docAgnosticFormat?: DocAgnosticFormat;
}
interface DocumentationState {}
const styles: Styles = {
mainContainers: {
@@ -81,57 +73,17 @@ const styles: Styles = {
},
};
export class Documentation extends React.Component<DocumentationAllProps, DocumentationState> {
private _isUnmounted: boolean;
constructor(props: DocumentationAllProps) {
super(props);
this._isUnmounted = false;
this.state = {
docAgnosticFormat: undefined,
};
}
public componentWillMount() {
const pathName = this.props.location.pathname;
const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
const versions = findVersions(lastSegment);
const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
// tslint:disable-next-line:no-floating-promises
this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
}
public componentWillUnmount() {
this._isUnmounted = true;
export class Documentation extends React.Component<DocumentationProps, DocumentationState> {
public componentDidUpdate(prevProps: DocumentationProps, prevState: DocumentationState) {
if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) {
this._scrollToHash();
}
}
public render() {
const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
? {}
: this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
return (
<div>
<DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
<TopBar
blockchainIsLoaded={false}
location={this.props.location}
docsVersion={this.props.docsVersion}
availableDocVersions={this.props.availableDocVersions}
menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
menuSubsectionsBySection={menuSubsectionsBySection}
docsInfo={this.props.docsInfo}
translate={this.props.translate}
/>
{_.isUndefined(this.state.docAgnosticFormat) ? (
<div className="col col-12" style={styles.mainContainers}>
<div
className="relative sm-px2 sm-pt2 sm-m1"
style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
>
<div className="center pb2">
<CircularProgress size={40} thickness={5} />
</div>
<div className="center pt2" style={{ paddingBottom: 11 }}>
Loading documentation...
</div>
</div>
</div>
{_.isUndefined(this.props.docAgnosticFormat) ? (
this._renderLoading()
) : (
<div style={{ width: '100%', height: '100%', backgroundColor: colors.gray40 }}>
<div
@@ -155,8 +107,7 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
versions={this.props.availableDocVersions}
title={this.props.docsInfo.displayName}
topLevelMenu={this.props.docsInfo.getMenu(this.props.docsVersion)}
menuSubsectionsBySection={menuSubsectionsBySection}
docPath={this.props.docsInfo.websitePath}
menuSubsectionsBySection={this.props.menuSubsectionsBySection}
/>
</div>
</div>
@@ -175,11 +126,28 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
</div>
);
}
private _renderLoading() {
return (
<div className="col col-12" style={styles.mainContainers}>
<div
className="relative sm-px2 sm-pt2 sm-m1"
style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
>
<div className="center pb2">
<CircularProgress size={40} thickness={5} />
</div>
<div className="center pt2" style={{ paddingBottom: 11 }}>
Loading documentation...
</div>
</div>
</div>
);
}
private _renderDocumentation(): React.ReactNode {
const subMenus = _.values(this.props.docsInfo.getMenu());
const orderedSectionNames = _.flatten(subMenus);
const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.state.docAgnosticFormat);
const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.props.docAgnosticFormat);
const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
return renderedSections;
@@ -196,7 +164,7 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
);
}
const docSection = this.state.docAgnosticFormat[sectionName];
const docSection = this.props.docAgnosticFormat[sectionName];
if (_.isUndefined(docSection)) {
return null;
}
@@ -278,7 +246,13 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
);
}
private _renderNetworkBadgesIfExists(sectionName: string) {
const networkToAddressByContractName = configs.CONTRACT_ADDRESS[this.props.docsVersion];
if (this.props.docsInfo.type !== SupportedDocJson.Doxity) {
return null;
}
const networkToAddressByContractName = this.props.docsInfo.contractsByVersionByNetworkId[
this.props.docsVersion
];
const badges = _.map(
networkToAddressByContractName,
(addressByContractName: AddressByContractName, networkName: string) => {
@@ -326,8 +300,7 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
<SourceLink
version={this.props.docsVersion}
source={property.source}
baseUrl={this.props.docsInfo.packageUrl}
subPackageName={this.props.docsInfo.subPackageName}
sourceUrl={this.props.sourceUrl}
/>
)}
{property.comment && <Comment comment={property.comment} className="py2" />}
@@ -348,6 +321,7 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
typeDefinitionByName={typeDefinitionByName}
libraryVersion={this.props.docsVersion}
docsInfo={this.props.docsInfo}
sourceUrl={this.props.sourceUrl}
/>
);
}
@@ -364,38 +338,4 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
containerId: 'documentation',
});
}
private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot);
const versions = _.keys(versionToFileName);
this.props.dispatcher.updateAvailableDocVersions(versions);
const sortedVersions = semverSort.desc(versions);
const latestVersion = sortedVersions[0];
let versionToFetch = latestVersion;
if (!_.isUndefined(preferredVersionIfExists)) {
const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
if (!_.isUndefined(preferredVersionFileNameIfExists)) {
versionToFetch = preferredVersionIfExists;
}
}
this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
const versionFileNameToFetch = versionToFileName[versionToFetch];
const versionDocObj = await docUtils.getJSONDocFileAsync(
versionFileNameToFetch,
this.props.docsInfo.docsJsonRoot,
);
const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
if (!this._isUnmounted) {
this.setState(
{
docAgnosticFormat,
},
() => {
this._scrollToHash();
},
);
}
}
}

View File

@@ -15,6 +15,7 @@ interface MethodBlockProps {
libraryVersion: string;
typeDefinitionByName: TypeDefinitionByName;
docsInfo: DocsInfo;
sourceUrl: string;
}
interface MethodBlockState {
@@ -80,8 +81,7 @@ export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockSt
<SourceLink
version={this.props.libraryVersion}
source={(method as TypescriptMethod).source}
baseUrl={this.props.docsInfo.packageUrl}
subPackageName={this.props.docsInfo.subPackageName}
sourceUrl={this.props.sourceUrl}
/>
)}
{method.comment && <Comment comment={method.comment} className="py2" />}

View File

@@ -5,22 +5,13 @@ import { colors } from 'ts/utils/colors';
interface SourceLinkProps {
source: Source;
baseUrl: string;
sourceUrl: string;
version: string;
subPackageName: string;
}
const packagesWithNamespace = ['connect'];
export function SourceLink(props: SourceLinkProps) {
const src = props.source;
const url = props.baseUrl;
const pkg = props.subPackageName;
let tagPrefix = pkg;
if (_.includes(packagesWithNamespace, pkg)) {
tagPrefix = `@0xproject/${pkg}`;
}
const sourceCodeUrl = `${url}/blob/${tagPrefix}%40${props.version}/packages/${pkg}/${src.fileName}#L${src.line}`;
const sourceCodeUrl = `${props.sourceUrl}/${src.fileName}#L${src.line}`;
return (
<div className="pt2" style={{ fontSize: 14 }}>
<a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}>

View File

@@ -16,7 +16,6 @@ interface NestedSidebarMenuProps {
onMenuItemClick?: () => void;
selectedVersion?: string;
versions?: string[];
docPath?: string;
}
interface NestedSidebarMenuState {}
@@ -69,13 +68,8 @@ export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, N
<div>
{this._renderEmblem()}
{!_.isUndefined(this.props.versions) &&
!_.isUndefined(this.props.selectedVersion) &&
!_.isUndefined(this.props.docPath) && (
<VersionDropDown
selectedVersion={this.props.selectedVersion}
versions={this.props.versions}
docPath={this.props.docPath}
/>
!_.isUndefined(this.props.selectedVersion) && (
<VersionDropDown selectedVersion={this.props.selectedVersion} versions={this.props.versions} />
)}
<div className="pl1">{navigation}</div>
</div>

View File

@@ -6,7 +6,6 @@ import * as React from 'react';
interface VersionDropDownProps {
selectedVersion: string;
versions: string[];
docPath: string;
}
interface VersionDropDownState {}
@@ -31,7 +30,17 @@ export class VersionDropDown extends React.Component<VersionDropDownProps, Versi
});
return items;
}
private _updateSelectedVersion(e: any, index: number, value: string) {
window.location.href = `${this.props.docPath}/${value}${window.location.hash}`;
private _updateSelectedVersion(e: any, index: number, semver: string) {
const port = window.location.port;
const hasPort = !_.isUndefined(port);
let path = window.location.pathname;
const lastChar = path[path.length - 1];
if (_.isFinite(_.parseInt(lastChar))) {
const pathSections = path.split('/');
pathSections.pop();
path = pathSections.join('/');
}
const baseUrl = `https://${window.location.hostname}${hasPort ? `:${port}` : ''}${path}`;
window.location.href = `${baseUrl}/${semver}${window.location.hash}`;
}
}

View File

@@ -627,20 +627,39 @@ export interface SectionsMap {
[sectionName: string]: string;
}
export enum DocPackages {
Connect = 'CONNECT',
ZeroExJs = 'ZERO_EX_JS',
SmartContracts = 'SMART_CONTRACTS',
}
export enum SupportedDocJson {
Doxity = 'DOXITY',
TypeDoc = 'TYPEDOC',
}
export interface ContractsByVersionByNetworkId {
[version: string]: {
[networkName: string]: {
[contractName: string]: string;
};
};
}
export interface DocsInfoConfig {
id: string;
type: SupportedDocJson;
displayName: string;
packageUrl: string;
websitePath: string;
docsJsonRoot: string;
menu: DocsMenu;
sections: SectionsMap;
sectionNameToMarkdown: { [sectionName: string]: string };
visibleConstructors: string[];
convertToDocAgnosticFormatFn: (docObj: DoxityDocObj | TypeDocNode, docsInfo?: any) => DocAgnosticFormat;
subPackageName?: string;
publicTypes?: string[];
sectionNameToModulePath?: { [sectionName: string]: string[] };
menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string };
contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
}
export interface TimestampMsRange {

View File

@@ -1,12 +1,5 @@
import * as _ from 'lodash';
import {
ContractAddresses,
Environments,
Networks,
OutdatedWrappedEtherByNetworkId,
PublicNodeUrlsByNetworkId,
SmartContractDocSections,
} from 'ts/types';
import { ContractAddresses, Environments, OutdatedWrappedEtherByNetworkId, PublicNodeUrlsByNetworkId } from 'ts/types';
const BASE_URL = window.location.origin;
const isDevelopment = _.includes(
@@ -19,34 +12,6 @@ export const configs = {
BACKEND_BASE_URL: 'https://website-api.0xproject.com',
BASE_URL,
BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
CONTRACT_ADDRESS: {
'1.0.0': {
[Networks.Mainnet]: {
[SmartContractDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
[SmartContractDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
[SmartContractDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
[SmartContractDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
},
[Networks.Ropsten]: {
[SmartContractDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
[SmartContractDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
[SmartContractDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
[SmartContractDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
},
[Networks.Kovan]: {
[SmartContractDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
[SmartContractDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
[SmartContractDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
[SmartContractDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
},
[Networks.Rinkeby]: {
[SmartContractDocSections.Exchange]: '0x1d16ef40fac01cec8adac2ac49427b9384192c05',
[SmartContractDocSections.TokenTransferProxy]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
[SmartContractDocSections.ZRXToken]: '0x00f58d6d585f84b2d7267940cede30ce2fe6eae8',
[SmartContractDocSections.TokenRegistry]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
},
},
} as ContractAddresses,
DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
// WARNING: ZRX & WETH MUST always be default trackedTokens
DEFAULT_TRACKED_TOKEN_SYMBOLS: ['WETH', 'ZRX'],

View File

@@ -42,6 +42,7 @@ export const constants = {
PROVIDER_NAME_GENERIC: 'Injected Web3',
PROVIDER_NAME_PUBLIC: '0x Public',
ROLLBAR_ACCESS_TOKEN: 'a6619002b51c4464928201e6ea94de65',
S3_BUCKET_ROOT: 'https://s3.amazonaws.com',
SUCCESS_STATUS: 200,
UNAVAILABLE_STATUS: 503,
TAKER_FEE: new BigNumber(0),

View File

@@ -4,6 +4,7 @@ import {
CustomType,
CustomTypeChild,
DocAgnosticFormat,
DocPackages,
DocSection,
IndexSignature,
KindString,
@@ -108,7 +109,7 @@ export const typeDocUtils = {
isConstructor,
docsInfo.sections,
sectionName,
docsInfo.subPackageName,
docsInfo.id,
);
docSection.constructors.push(constructor);
break;
@@ -121,7 +122,7 @@ export const typeDocUtils = {
isConstructor,
docsInfo.sections,
sectionName,
docsInfo.subPackageName,
docsInfo.id,
);
docSection.methods.push(method);
}
@@ -133,7 +134,7 @@ export const typeDocUtils = {
entity,
docsInfo.sections,
sectionName,
docsInfo.subPackageName,
docsInfo.id,
);
docSection.properties.push(property);
}
@@ -149,7 +150,7 @@ export const typeDocUtils = {
entity,
docsInfo.sections,
sectionName,
docsInfo.subPackageName,
docsInfo.id,
);
docSection.types.push(customType);
}
@@ -161,21 +162,16 @@ export const typeDocUtils = {
});
return docSection;
},
_convertCustomType(
entity: TypeDocNode,
sections: SectionsMap,
sectionName: string,
subPackageName: string,
): CustomType {
_convertCustomType(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): CustomType {
const typeIfExists = !_.isUndefined(entity.type)
? typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName)
? typeDocUtils._convertType(entity.type, sections, sectionName, docId)
: undefined;
const isConstructor = false;
const methodIfExists = !_.isUndefined(entity.declaration)
? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
: undefined;
const indexSignatureIfExists = !_.isUndefined(entity.indexSignature)
? typeDocUtils._convertIndexSignature(entity.indexSignature[0], sections, sectionName, subPackageName)
? typeDocUtils._convertIndexSignature(entity.indexSignature[0], sections, sectionName, docId)
: undefined;
const commentIfExists =
!_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText)
@@ -185,7 +181,7 @@ export const typeDocUtils = {
const childrenIfExist = !_.isUndefined(entity.children)
? _.map(entity.children, (child: TypeDocNode) => {
const childTypeIfExists = !_.isUndefined(child.type)
? typeDocUtils._convertType(child.type, sections, sectionName, subPackageName)
? typeDocUtils._convertType(child.type, sections, sectionName, docId)
: undefined;
const c: CustomTypeChild = {
name: child.name,
@@ -212,27 +208,22 @@ export const typeDocUtils = {
entity: TypeDocNode,
sections: SectionsMap,
sectionName: string,
subPackageName: string,
docId: string,
): IndexSignature {
const key = entity.parameters[0];
const indexSignature = {
keyName: key.name,
keyType: typeDocUtils._convertType(key.type, sections, sectionName, subPackageName),
keyType: typeDocUtils._convertType(key.type, sections, sectionName, docId),
valueName: entity.type.name,
};
return indexSignature;
},
_convertProperty(
entity: TypeDocNode,
sections: SectionsMap,
sectionName: string,
subPackageName: string,
): Property {
_convertProperty(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Property {
const source = entity.sources[0];
const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined;
const property = {
name: entity.name,
type: typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName),
type: typeDocUtils._convertType(entity.type, sections, sectionName, docId),
source: {
fileName: source.fileName,
line: source.line,
@@ -246,7 +237,7 @@ export const typeDocUtils = {
isConstructor: boolean,
sections: SectionsMap,
sectionName: string,
subPackageName: string,
docId: string,
): TypescriptMethod {
const signature = entity.signatures[0];
const source = entity.sources[0];
@@ -258,7 +249,7 @@ export const typeDocUtils = {
let callPath;
if (isConstructor || entity.name === '__type') {
callPath = '';
} else if (subPackageName === '0x.js') {
} else if (docId === DocPackages.ZeroExJs) {
const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.';
callPath =
!_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx
@@ -269,12 +260,12 @@ export const typeDocUtils = {
}
const parameters = _.map(signature.parameters, param => {
return typeDocUtils._convertParameter(param, sections, sectionName, subPackageName);
return typeDocUtils._convertParameter(param, sections, sectionName, docId);
});
const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, subPackageName);
const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, docId);
const typeParameter = _.isUndefined(signature.typeParameter)
? undefined
: typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, subPackageName);
: typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, docId);
const method = {
isConstructor,
@@ -297,21 +288,16 @@ export const typeDocUtils = {
entity: TypeDocNode,
sections: SectionsMap,
sectionName: string,
subPackageName: string,
docId: string,
): TypeParameter {
const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
const parameter = {
name: entity.name,
type,
};
return parameter;
},
_convertParameter(
entity: TypeDocNode,
sections: SectionsMap,
sectionName: string,
subPackageName: string,
): Parameter {
_convertParameter(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Parameter {
let comment = '<No comment>';
if (entity.comment && entity.comment.shortText) {
comment = entity.comment.shortText;
@@ -321,7 +307,7 @@ export const typeDocUtils = {
const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false;
const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
const parameter = {
name: entity.name,
@@ -331,17 +317,17 @@ export const typeDocUtils = {
};
return parameter;
},
_convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, subPackageName: string): Type {
_convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, docId: string): Type {
const typeArguments = _.map(entity.typeArguments, typeArgument => {
return typeDocUtils._convertType(typeArgument, sections, sectionName, subPackageName);
return typeDocUtils._convertType(typeArgument, sections, sectionName, docId);
});
const types = _.map(entity.types, t => {
return typeDocUtils._convertType(t, sections, sectionName, subPackageName);
return typeDocUtils._convertType(t, sections, sectionName, docId);
});
const isConstructor = false;
const methodIfExists = !_.isUndefined(entity.declaration)
? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
: undefined;
const elementTypeIfExists = !_.isUndefined(entity.elementType)