Add website to mono repo, update packages to align with existing sub-packages, use new subscribeAsync 0x.js method
This commit is contained in:
@@ -0,0 +1,340 @@
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import * as ReactMarkdown from 'react-markdown';
|
||||
import DocumentTitle = require('react-document-title');
|
||||
import findVersions = require('find-versions');
|
||||
import semverSort = require('semver-sort');
|
||||
import {colors} from 'material-ui/styles';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import CircularProgress from 'material-ui/CircularProgress';
|
||||
import Paper from 'material-ui/Paper';
|
||||
import {
|
||||
Link as ScrollLink,
|
||||
Element as ScrollElement,
|
||||
scroller,
|
||||
} from 'react-scroll';
|
||||
import {Dispatcher} from 'ts/redux/dispatcher';
|
||||
import {
|
||||
KindString,
|
||||
TypeDocNode,
|
||||
ZeroExJsDocSections,
|
||||
Styles,
|
||||
ScreenWidths,
|
||||
TypeDefinitionByName,
|
||||
DocAgnosticFormat,
|
||||
TypescriptMethod,
|
||||
Property,
|
||||
CustomType,
|
||||
Docs,
|
||||
} from 'ts/types';
|
||||
import {TopBar} from 'ts/components/top_bar';
|
||||
import {utils} from 'ts/utils/utils';
|
||||
import {docUtils} from 'ts/utils/doc_utils';
|
||||
import {constants} from 'ts/utils/constants';
|
||||
import {Loading} from 'ts/components/ui/loading';
|
||||
import {MethodBlock} from 'ts/pages/documentation/method_block';
|
||||
import {SourceLink} from 'ts/pages/documentation/source_link';
|
||||
import {Type} from 'ts/pages/documentation/type';
|
||||
import {TypeDefinition} from 'ts/pages/documentation/type_definition';
|
||||
import {MarkdownSection} from 'ts/pages/shared/markdown_section';
|
||||
import {Comment} from 'ts/pages/documentation/comment';
|
||||
import {AnchorTitle} from 'ts/pages/shared/anchor_title';
|
||||
import {SectionHeader} from 'ts/pages/shared/section_header';
|
||||
import {NestedSidebarMenu} from 'ts/pages/shared/nested_sidebar_menu';
|
||||
import {typeDocUtils} from 'ts/utils/typedoc_utils';
|
||||
/* tslint:disable:no-var-requires */
|
||||
const IntroMarkdown = require('md/docs/0xjs/introduction');
|
||||
const InstallationMarkdown = require('md/docs/0xjs/installation');
|
||||
const AsyncMarkdown = require('md/docs/0xjs/async');
|
||||
const ErrorsMarkdown = require('md/docs/0xjs/errors');
|
||||
const versioningMarkdown = require('md/docs/0xjs/versioning');
|
||||
/* tslint:enable:no-var-requires */
|
||||
|
||||
const SCROLL_TO_TIMEOUT = 500;
|
||||
const DOC_JSON_ROOT = constants.S3_0XJS_DOCUMENTATION_JSON_ROOT;
|
||||
|
||||
const sectionNameToMarkdown = {
|
||||
[ZeroExJsDocSections.introduction]: IntroMarkdown,
|
||||
[ZeroExJsDocSections.installation]: InstallationMarkdown,
|
||||
[ZeroExJsDocSections.async]: AsyncMarkdown,
|
||||
[ZeroExJsDocSections.errors]: ErrorsMarkdown,
|
||||
[ZeroExJsDocSections.versioning]: versioningMarkdown,
|
||||
};
|
||||
|
||||
export interface ZeroExJSDocumentationPassedProps {
|
||||
source: string;
|
||||
location: Location;
|
||||
}
|
||||
|
||||
export interface ZeroExJSDocumentationAllProps {
|
||||
source: string;
|
||||
location: Location;
|
||||
dispatcher: Dispatcher;
|
||||
docsVersion: string;
|
||||
availableDocVersions: string[];
|
||||
}
|
||||
|
||||
interface ZeroExJSDocumentationState {
|
||||
docAgnosticFormat?: DocAgnosticFormat;
|
||||
}
|
||||
|
||||
const styles: Styles = {
|
||||
mainContainers: {
|
||||
position: 'absolute',
|
||||
top: 60,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
overflowZ: 'hidden',
|
||||
overflowY: 'scroll',
|
||||
minHeight: 'calc(100vh - 60px)',
|
||||
WebkitOverflowScrolling: 'touch',
|
||||
},
|
||||
menuContainer: {
|
||||
borderColor: colors.grey300,
|
||||
maxWidth: 330,
|
||||
marginLeft: 20,
|
||||
},
|
||||
};
|
||||
|
||||
export class ZeroExJSDocumentation extends React.Component<ZeroExJSDocumentationAllProps, ZeroExJSDocumentationState> {
|
||||
constructor(props: ZeroExJSDocumentationAllProps) {
|
||||
super(props);
|
||||
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;
|
||||
this.fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
|
||||
}
|
||||
public render() {
|
||||
const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
|
||||
? {}
|
||||
: typeDocUtils.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
|
||||
return (
|
||||
<div>
|
||||
<DocumentTitle title="0x.js Documentation"/>
|
||||
<TopBar
|
||||
blockchainIsLoaded={false}
|
||||
location={this.props.location}
|
||||
docsVersion={this.props.docsVersion}
|
||||
availableDocVersions={this.props.availableDocVersions}
|
||||
menuSubsectionsBySection={menuSubsectionsBySection}
|
||||
shouldFullWidth={true}
|
||||
doc={Docs.ZeroExJs}
|
||||
/>
|
||||
{_.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> :
|
||||
<div
|
||||
className="mx-auto flex"
|
||||
style={{color: colors.grey800, height: 43}}
|
||||
>
|
||||
<div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
|
||||
<div
|
||||
className="border-right absolute"
|
||||
style={{...styles.menuContainer, ...styles.mainContainers}}
|
||||
>
|
||||
<NestedSidebarMenu
|
||||
selectedVersion={this.props.docsVersion}
|
||||
versions={this.props.availableDocVersions}
|
||||
topLevelMenu={typeDocUtils.getFinal0xjsMenu(this.props.docsVersion)}
|
||||
menuSubsectionsBySection={menuSubsectionsBySection}
|
||||
doc={Docs.ZeroExJs}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
|
||||
<div
|
||||
id="documentation"
|
||||
style={styles.mainContainers}
|
||||
className="absolute"
|
||||
>
|
||||
<div id="zeroExJSDocs" />
|
||||
<h1 className="md-pl2 sm-pl3">
|
||||
<a href={constants.GITHUB_0X_JS_URL} target="_blank">
|
||||
0x.js
|
||||
</a>
|
||||
</h1>
|
||||
{this.renderDocumentation()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private renderDocumentation(): React.ReactNode {
|
||||
const typeDocSection = this.state.docAgnosticFormat[ZeroExJsDocSections.types];
|
||||
const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name');
|
||||
|
||||
const subMenus = _.values(constants.menu0xjs);
|
||||
const orderedSectionNames = _.flatten(subMenus);
|
||||
const sections = _.map(orderedSectionNames, this.renderSection.bind(this, typeDefinitionByName));
|
||||
|
||||
return sections;
|
||||
}
|
||||
private renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
|
||||
const docSection = this.state.docAgnosticFormat[sectionName];
|
||||
|
||||
const markdownFileIfExists = sectionNameToMarkdown[sectionName];
|
||||
if (!_.isUndefined(markdownFileIfExists)) {
|
||||
return (
|
||||
<MarkdownSection
|
||||
key={`markdown-section-${sectionName}`}
|
||||
sectionName={sectionName}
|
||||
markdownContent={markdownFileIfExists}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (_.isUndefined(docSection)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const typeDefs = _.map(docSection.types, customType => {
|
||||
return (
|
||||
<TypeDefinition
|
||||
key={`type-${customType.name}`}
|
||||
customType={customType}
|
||||
/>
|
||||
);
|
||||
});
|
||||
const propertyDefs = _.map(docSection.properties, this.renderProperty.bind(this));
|
||||
const methodDefs = _.map(docSection.methods, method => {
|
||||
const isConstructor = false;
|
||||
return this.renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName);
|
||||
});
|
||||
return (
|
||||
<div
|
||||
key={`section-${sectionName}`}
|
||||
className="py2 pr3 md-pl2 sm-pl3"
|
||||
>
|
||||
<SectionHeader sectionName={sectionName} />
|
||||
<Comment
|
||||
comment={docSection.comment}
|
||||
/>
|
||||
{sectionName === ZeroExJsDocSections.zeroEx && docSection.constructors.length > 0 &&
|
||||
<div>
|
||||
<h2 className="thin">Constructor</h2>
|
||||
{this.renderZeroExConstructors(docSection.constructors, typeDefinitionByName)}
|
||||
</div>
|
||||
}
|
||||
{docSection.properties.length > 0 &&
|
||||
<div>
|
||||
<h2 className="thin">Properties</h2>
|
||||
<div>{propertyDefs}</div>
|
||||
</div>
|
||||
}
|
||||
{docSection.methods.length > 0 &&
|
||||
<div>
|
||||
<h2 className="thin">Methods</h2>
|
||||
<div>{methodDefs}</div>
|
||||
</div>
|
||||
}
|
||||
{typeDefs.length > 0 &&
|
||||
<div>
|
||||
<div>{typeDefs}</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private renderZeroExConstructors(constructors: TypescriptMethod[],
|
||||
typeDefinitionByName: TypeDefinitionByName): React.ReactNode {
|
||||
const constructorDefs = _.map(constructors, constructor => {
|
||||
return this.renderMethodBlocks(
|
||||
constructor, ZeroExJsDocSections.zeroEx, constructor.isConstructor, typeDefinitionByName,
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
{constructorDefs}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private renderProperty(property: Property): React.ReactNode {
|
||||
return (
|
||||
<div
|
||||
key={`property-${property.name}-${property.type.name}`}
|
||||
className="pb3"
|
||||
>
|
||||
<code className="hljs">
|
||||
{property.name}: <Type type={property.type} />
|
||||
</code>
|
||||
<SourceLink
|
||||
version={this.props.docsVersion}
|
||||
source={property.source}
|
||||
/>
|
||||
{property.comment &&
|
||||
<Comment
|
||||
comment={property.comment}
|
||||
className="py2"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private renderMethodBlocks(method: TypescriptMethod, sectionName: string, isConstructor: boolean,
|
||||
typeDefinitionByName: TypeDefinitionByName): React.ReactNode {
|
||||
return (
|
||||
<MethodBlock
|
||||
key={`method-${method.name}-${!_.isUndefined(method.source) ? method.source.line : ''}`}
|
||||
method={method}
|
||||
typeDefinitionByName={typeDefinitionByName}
|
||||
libraryVersion={this.props.docsVersion}
|
||||
/>
|
||||
);
|
||||
}
|
||||
private scrollToHash(): void {
|
||||
const hashWithPrefix = this.props.location.hash;
|
||||
let hash = hashWithPrefix.slice(1);
|
||||
if (_.isEmpty(hash)) {
|
||||
hash = 'zeroExJSDocs'; // scroll to the top
|
||||
}
|
||||
|
||||
scroller.scrollTo(hash, {duration: 0, offset: 0, containerId: 'documentation'});
|
||||
}
|
||||
private async fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
|
||||
const versionToFileName = await docUtils.getVersionToFileNameAsync(DOC_JSON_ROOT);
|
||||
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, DOC_JSON_ROOT);
|
||||
const docAgnosticFormat = typeDocUtils.convertToDocAgnosticFormat((versionDocObj as TypeDocNode));
|
||||
|
||||
this.setState({
|
||||
docAgnosticFormat,
|
||||
}, () => {
|
||||
this.scrollToHash();
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user