Begin refactoring out doc generator template
This commit is contained in:
@@ -2,8 +2,8 @@ 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';
|
||||
@@ -91,7 +91,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,
|
||||
@@ -102,6 +102,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,
|
||||
);
|
||||
|
@@ -2,8 +2,8 @@ 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';
|
||||
@@ -49,7 +49,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 +60,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,
|
||||
);
|
||||
|
@@ -2,8 +2,8 @@ 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';
|
||||
@@ -162,7 +162,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 +173,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,
|
||||
);
|
||||
|
107
packages/website/ts/pages/documentation/doc_page.tsx
Normal file
107
packages/website/ts/pages/documentation/doc_page.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
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, DoxityDocObj, MenuSubsectionsBySection } from 'ts/types';
|
||||
import { docUtils } from 'ts/utils/doc_utils';
|
||||
import { Translate } from 'ts/utils/translate';
|
||||
|
||||
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);
|
||||
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}
|
||||
dispatcher={this.props.dispatcher}
|
||||
docsVersion={this.props.docsVersion}
|
||||
availableDocVersions={this.props.availableDocVersions}
|
||||
docsInfo={this.props.docsInfo}
|
||||
translate={this.props.translate}
|
||||
docAgnosticFormat={this.state.docAgnosticFormat}
|
||||
menuSubsectionsBySection={menuSubsectionsBySection}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -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';
|
||||
@@ -24,6 +20,7 @@ import {
|
||||
DoxityDocObj,
|
||||
EtherscanLinkSuffixes,
|
||||
Event,
|
||||
MenuSubsectionsBySection,
|
||||
Networks,
|
||||
Property,
|
||||
SolidityMethod,
|
||||
@@ -34,7 +31,6 @@ import {
|
||||
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';
|
||||
|
||||
@@ -48,19 +44,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;
|
||||
docAgnosticFormat?: DocAgnosticFormat;
|
||||
menuSubsectionsBySection: MenuSubsectionsBySection;
|
||||
}
|
||||
|
||||
interface DocumentationState {
|
||||
docAgnosticFormat?: DocAgnosticFormat;
|
||||
}
|
||||
interface DocumentationState {}
|
||||
|
||||
const styles: Styles = {
|
||||
mainContainers: {
|
||||
@@ -81,57 +76,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,7 +110,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}
|
||||
menuSubsectionsBySection={this.props.menuSubsectionsBySection}
|
||||
docPath={this.props.docsInfo.websitePath}
|
||||
/>
|
||||
</div>
|
||||
@@ -175,11 +130,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 +168,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;
|
||||
}
|
||||
@@ -364,38 +336,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();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user