|
@@ -1,81 +1,92 @@
|
|
|
-import React, { Component, ComponentClass } from 'react';
|
|
|
|
|
|
|
+// Library
|
|
|
|
|
+import React, { Component } from 'react';
|
|
|
|
|
|
|
|
-export interface OuterProps {
|
|
|
|
|
- type: string;
|
|
|
|
|
- queries: any[];
|
|
|
|
|
- isVisible: boolean;
|
|
|
|
|
|
|
+interface RenderProps {
|
|
|
|
|
+ loading: LoadingState;
|
|
|
|
|
+ data: any;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export interface PanelProps extends OuterProps {
|
|
|
|
|
- data: any[];
|
|
|
|
|
|
|
+export interface Props {
|
|
|
|
|
+ datasource: string | null;
|
|
|
|
|
+ queries: any[];
|
|
|
|
|
+ children: (r: RenderProps) => JSX.Element;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export interface DataPanel extends ComponentClass<OuterProps> {}
|
|
|
|
|
-
|
|
|
|
|
-interface State {
|
|
|
|
|
- isLoading: boolean;
|
|
|
|
|
- data: any[];
|
|
|
|
|
|
|
+export interface State {
|
|
|
|
|
+ isFirstLoad: boolean;
|
|
|
|
|
+ loading: LoadingState;
|
|
|
|
|
+ data: any;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export const DataPanelWrapper = (ComposedComponent: ComponentClass<PanelProps>) => {
|
|
|
|
|
- class Wrapper extends Component<OuterProps, State> {
|
|
|
|
|
- static defaultProps = {
|
|
|
|
|
- isVisible: true,
|
|
|
|
|
- };
|
|
|
|
|
|
|
+export enum LoadingState {
|
|
|
|
|
+ NotStarted = 'NotStarted',
|
|
|
|
|
+ Loading = 'Loading',
|
|
|
|
|
+ Done = 'Done',
|
|
|
|
|
+ Error = 'Error',
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- constructor(props: OuterProps) {
|
|
|
|
|
- super(props);
|
|
|
|
|
|
|
+export interface PanelProps extends RenderProps {}
|
|
|
|
|
|
|
|
- this.state = {
|
|
|
|
|
- isLoading: false,
|
|
|
|
|
- data: [],
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
|
|
+export class DataPanel extends Component<Props, State> {
|
|
|
|
|
+ constructor(props: Props) {
|
|
|
|
|
+ super(props);
|
|
|
|
|
|
|
|
- componentDidMount() {
|
|
|
|
|
- console.log('data panel mount');
|
|
|
|
|
- this.issueQueries();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ this.state = {
|
|
|
|
|
+ loading: LoadingState.NotStarted,
|
|
|
|
|
+ data: [],
|
|
|
|
|
+ isFirstLoad: true,
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- issueQueries = async () => {
|
|
|
|
|
- const { isVisible } = this.props;
|
|
|
|
|
|
|
+ componentDidMount() {
|
|
|
|
|
+ console.log('DataPanel mount');
|
|
|
|
|
+ this.issueQueries();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (!isVisible) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ issueQueries = async () => {
|
|
|
|
|
+ this.setState({ loading: LoadingState.Loading });
|
|
|
|
|
+
|
|
|
|
|
+ await new Promise(resolve => {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ this.setState({ loading: LoadingState.Done, data: [{ value: 10 }], isFirstLoad: false });
|
|
|
|
|
+ }, 500);
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ render() {
|
|
|
|
|
+ const { data, loading, isFirstLoad } = this.state;
|
|
|
|
|
+ console.log('data panel render');
|
|
|
|
|
+
|
|
|
|
|
+ if (isFirstLoad && loading === LoadingState.Loading) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div className="loading">
|
|
|
|
|
+ <p>Loading</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- this.setState({ isLoading: true });
|
|
|
|
|
|
|
+ return (
|
|
|
|
|
+ <>
|
|
|
|
|
+ {this.loadingSpinner}
|
|
|
|
|
+ {this.props.children({
|
|
|
|
|
+ data,
|
|
|
|
|
+ loading,
|
|
|
|
|
+ })}
|
|
|
|
|
+ </>
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- await new Promise(resolve => {
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- this.setState({ isLoading: false, data: [{ value: 10 }] });
|
|
|
|
|
- }, 500);
|
|
|
|
|
- });
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ private get loadingSpinner(): JSX.Element {
|
|
|
|
|
+ const { loading } = this.state;
|
|
|
|
|
|
|
|
- render() {
|
|
|
|
|
- const { data, isLoading } = this.state;
|
|
|
|
|
- console.log('data panel render');
|
|
|
|
|
-
|
|
|
|
|
- if (!data.length) {
|
|
|
|
|
- return (
|
|
|
|
|
- <div className="no-data">
|
|
|
|
|
- <p>No Data</p>
|
|
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (isLoading) {
|
|
|
|
|
- return (
|
|
|
|
|
- <div className="loading">
|
|
|
|
|
- <p>Loading</p>
|
|
|
|
|
- </div>
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return <ComposedComponent {...this.props} data={data} />;
|
|
|
|
|
|
|
+ if (loading === LoadingState.Loading) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div className="panel__loading">
|
|
|
|
|
+ <i className="fa fa-spinner fa-spin" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- return Wrapper;
|
|
|
|
|
-};
|
|
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|