diff options
author | Brandon Millman <brandon.millman@gmail.com> | 2018-03-02 05:04:55 +0800 |
---|---|---|
committer | Brandon Millman <brandon.millman@gmail.com> | 2018-03-02 05:04:55 +0800 |
commit | 0c16f0ea221d65e66942c27a69dda1c54f49e775 (patch) | |
tree | 5530d18fcd6e6c5e15272de3cb915fc2025c01bf /packages/website/ts/pages | |
parent | 003d43b03ae373ca24d6d728ffa6b0f2dfcda79a (diff) | |
parent | 451a0dacbe85d7a0d16ef007c1eb945a4c1977cb (diff) | |
download | dexon-0x-contracts-0c16f0ea221d65e66942c27a69dda1c54f49e775.tar dexon-0x-contracts-0c16f0ea221d65e66942c27a69dda1c54f49e775.tar.gz dexon-0x-contracts-0c16f0ea221d65e66942c27a69dda1c54f49e775.tar.bz2 dexon-0x-contracts-0c16f0ea221d65e66942c27a69dda1c54f49e775.tar.lz dexon-0x-contracts-0c16f0ea221d65e66942c27a69dda1c54f49e775.tar.xz dexon-0x-contracts-0c16f0ea221d65e66942c27a69dda1c54f49e775.tar.zst dexon-0x-contracts-0c16f0ea221d65e66942c27a69dda1c54f49e775.zip |
Merge branch 'development' into feature/sra-reporter
* development: (71 commits)
Set max to 2 ETH/2 ZRX
Add missing types from website
Add dependencies
Update the README
Move BaseContract to its own package
Upgrate prettier
remove unused import
Move more configs into docsInfo and remove logic that does not belong there elsewhere
Fix a bug with displaying solidity functions returning multiple return values
Add ethers-contracts as a dependency
Include types for ethers-contracts
Fix the version
Include types for ethers-contracts
Rename idx to i
Remove tslint disable
Move BaseContract to web3Wrapper
Merge ifs
Fix an option description
Add link to the docs
Improve CHANGELOG entry
...
Diffstat (limited to 'packages/website/ts/pages')
7 files changed, 208 insertions, 134 deletions
diff --git a/packages/website/ts/pages/documentation/doc_page.tsx b/packages/website/ts/pages/documentation/doc_page.tsx new file mode 100644 index 000000000..2c8f1c103 --- /dev/null +++ b/packages/website/ts/pages/documentation/doc_page.tsx @@ -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; + } +} diff --git a/packages/website/ts/pages/documentation/docs_info.ts b/packages/website/ts/pages/documentation/docs_info.ts index 4b1ec122a..31e151fe8 100644 --- a/packages/website/ts/pages/documentation/docs_info.ts +++ b/packages/website/ts/pages/documentation/docs_info.ts @@ -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); + } } } diff --git a/packages/website/ts/pages/documentation/documentation.tsx b/packages/website/ts/pages/documentation/documentation.tsx index 285471166..7eed78fc3 100644 --- a/packages/website/ts/pages/documentation/documentation.tsx +++ b/packages/website/ts/pages/documentation/documentation.tsx @@ -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,20 +42,18 @@ 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; -} - -interface DocumentationState { docAgnosticFormat?: DocAgnosticFormat; + menuSubsectionsBySection: MenuSubsectionsBySection; + sourceUrl: string; } +interface DocumentationState {} + const styles: Styles = { mainContainers: { position: 'absolute', @@ -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(); - }, - ); - } - } } diff --git a/packages/website/ts/pages/documentation/method_block.tsx b/packages/website/ts/pages/documentation/method_block.tsx index 1bc6aa4f4..d2c96bf8c 100644 --- a/packages/website/ts/pages/documentation/method_block.tsx +++ b/packages/website/ts/pages/documentation/method_block.tsx @@ -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" />} diff --git a/packages/website/ts/pages/documentation/source_link.tsx b/packages/website/ts/pages/documentation/source_link.tsx index 6588ee39e..31f80aba3 100644 --- a/packages/website/ts/pages/documentation/source_link.tsx +++ b/packages/website/ts/pages/documentation/source_link.tsx @@ -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 }}> diff --git a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx index ba794ee9f..1a08ca9f9 100644 --- a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx +++ b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx @@ -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> diff --git a/packages/website/ts/pages/shared/version_drop_down.tsx b/packages/website/ts/pages/shared/version_drop_down.tsx index b922e1048..3b331af9b 100644 --- a/packages/website/ts/pages/shared/version_drop_down.tsx +++ b/packages/website/ts/pages/shared/version_drop_down.tsx @@ -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}`; } } |