redoc/src/components/StoreProvider.ts

95 lines
2.0 KiB
TypeScript
Raw Normal View History

import { Component } from 'react';
import { AppStore } from '../services/';
2017-11-21 14:00:33 +03:00
import { RedocRawOptions } from '../services/RedocNormalizedOptions';
import { OpenAPISpec } from '../types';
2018-03-13 14:04:55 +03:00
import { loadAndBundleSpec } from '../utils';
2017-10-12 00:01:37 +03:00
2018-05-16 12:44:36 +03:00
export interface StoreProviderProps {
2017-10-12 00:01:37 +03:00
specUrl?: string;
spec?: object;
store?: AppStore;
2017-11-21 14:00:33 +03:00
options?: RedocRawOptions;
children: (props: { loading: boolean; store?: AppStore }) => any;
2017-10-12 00:01:37 +03:00
}
2018-05-16 12:44:36 +03:00
export interface StoreProviderState {
error?: Error;
loading: boolean;
store?: AppStore;
}
2017-10-12 00:01:37 +03:00
export class StoreProvider extends Component<StoreProviderProps, StoreProviderState> {
store: AppStore;
2017-10-12 00:01:37 +03:00
private _resolvedSpec: OpenAPISpec;
constructor(props: StoreProviderProps) {
2017-10-12 00:01:37 +03:00
super(props);
this.state = {
loading: true,
};
2017-11-20 02:00:43 +03:00
}
2017-11-20 02:00:43 +03:00
componentDidMount() {
this.load();
}
async load() {
2018-01-22 21:30:53 +03:00
const { specUrl, spec, options } = this.props;
this.setState({
loading: true,
});
try {
this._resolvedSpec = await loadAndBundleSpec(spec || specUrl!);
this.updateStore(this._resolvedSpec, specUrl, options);
} catch (e) {
this.setState({
error: e,
});
}
}
updateStore(resolvedSpec, specUrl, options) {
try {
this.setState({
loading: false,
2017-11-21 14:00:33 +03:00
store: new AppStore(resolvedSpec, specUrl, options),
error: undefined,
});
} catch (e) {
this.setState({
error: e,
});
2017-10-12 00:01:37 +03:00
}
}
componentWillReceiveProps(nextProps) {
if (this.props.specUrl !== nextProps.specUrl || this.props.spec !== nextProps.spec) {
setTimeout(() => this.load(), 0);
return;
}
if (this.props.options !== nextProps.options && this._resolvedSpec) {
this.updateStore(this._resolvedSpec, nextProps.specUrl, nextProps.options);
}
}
2017-10-12 00:01:37 +03:00
setError(e?: Error) {
this.setState({
error: e,
});
}
render() {
2018-01-22 21:30:53 +03:00
if (this.state.error) {
throw this.state.error;
}
return this.props.children(this.state);
2017-10-12 00:01:37 +03:00
}
}