diff --git a/src/components/logs-list/LogsList.js b/src/components/logs-list/LogsList.js index ce553a4..62a49ce 100644 --- a/src/components/logs-list/LogsList.js +++ b/src/components/logs-list/LogsList.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { Component } from "react"; import PropTypes from "prop-types"; import { Table } from "semantic-ui-react"; @@ -30,33 +30,53 @@ Log.propTypes = { type: PropTypes.string }; -export const LogsList = ({ logs = [], logsLoading, showPlaceHolders }) => { - const placeHolders = []; - if (logsLoading && showPlaceHolders) { - for (let i = 0; i < showPlaceHolders + 1; i++) { - placeHolders.push(); +export class LogsList extends Component { + constructor(props) { + super(props); + this.state = { + loaded: props.logsLoading + }; + } + + componentDidUpdate() { + if (!this.state.loaded && this.props.logsLoading === false && this.props.onLoaded) { + this.setState({ + loaded: true + }); + this.props.onLoaded(); } - return {placeHolders.map(placeHolder => placeHolder)}; } - return ( - - {!showPlaceHolders && logs.length < 1 && !logsLoading ? : null} - {logs.map(log => ( - - ))} - - ); -}; + + render() { + const placeHolders = []; + const { logs = [], logsLoading, showPlaceHolders } = this.props; + if (logsLoading && showPlaceHolders) { + for (let i = 0; i < showPlaceHolders + 1; i++) { + placeHolders.push(); + } + return {placeHolders.map(placeHolder => placeHolder)}; + } + return ( + + {!showPlaceHolders && logs.length < 1 && !logsLoading ? : null} + {logs.map(log => ( + + ))} + + ); + } +} LogsList.propTypes = { logs: PropTypes.array, logsLoading: PropTypes.bool, + onLoaded: PropTypes.func, showPlaceHolders: PropTypes.number }; diff --git a/src/components/scroll-paginated-list/ScrollPaginatedList.js b/src/components/scroll-paginated-list/ScrollPaginatedList.js index de556bd..83abbd1 100644 --- a/src/components/scroll-paginated-list/ScrollPaginatedList.js +++ b/src/components/scroll-paginated-list/ScrollPaginatedList.js @@ -8,15 +8,29 @@ export class ScrollPaginatedList extends Component { constructor(props) { super(props); this.state = { - currentPage: 1 + currentPage: 1, + hasLoaded: {} }; this.loadMore = this.loadMore.bind(this); + this.setLoaded = this.setLoaded.bind(this); } loadMore(page) { - this.setState({ + this.setState(state => ({ + ...state, currentPage: page - }); + })); + } + + setLoaded(listId) { + console.log("loaded", listId); + this.setState(state => ({ + ...state, + hasLoaded: { + ...state.hasLoaded, + [listId]: true + } + })); } hasMore() { @@ -28,12 +42,18 @@ export class ScrollPaginatedList extends Component { const ListWrapper = this.props.ListWrapper; const pages = []; for (let i = 1; i < this.state.currentPage + 1; i++) { + const listId = `paginated-list-${i}`; pages.push( { + if (!this.state.hasLoaded[listId]) { + this.setLoaded(listId); + } + }} /> ); } diff --git a/src/data-layer/login.js b/src/data-layer/login.js index 6f821e0..925c58f 100644 --- a/src/data-layer/login.js +++ b/src/data-layer/login.js @@ -10,6 +10,7 @@ class Login { this._doLogin = this._doLogin.bind(this); this._refreshToken = authSession.refreshToken(); this._apiKey = authSession.apiKey(); + this._loginPromise = null; } _doLogin(dataSources, retry) { @@ -19,27 +20,34 @@ class Login { const refreshToken = tokens[0]; const apiKey = tokens[1]; if (refreshToken) { - return authJwt - .create({ + this._loginPromise = + this._loginPromise || + authJwt.create({ refreshToken - }) - .then(response => { - setJwtAuth(response.accessToken); - return retry(); }); + return this._loginPromise.then(response => { + setJwtAuth(response.accessToken); + return retry(); + }); } else if (apiKey) { setApiKeyAuth(apiKey); return retry(); } return Promise.reject(noAuthenticationTokenError); }) + .then(results => { + this._loginPromise = null; + return Promise.resolve(results); + }) .catch(error => { + this._loginPromise = null; if (error === noAuthenticationTokenError || error.message === "Unauthorized") { return this.logout().then(() => Promise.reject(error)); } else { return Promise.reject(error); } }); + return this._loginPromise; } _configDataSources() { diff --git a/src/modules/dashboard/components/dashboard-layout/DashboardLayout.js b/src/modules/dashboard/components/dashboard-layout/DashboardLayout.js index 3c10204..494a8d7 100644 --- a/src/modules/dashboard/components/dashboard-layout/DashboardLayout.js +++ b/src/modules/dashboard/components/dashboard-layout/DashboardLayout.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { Component } from "react"; import PropTypes from "prop-types"; import { Segment } from "semantic-ui-react"; @@ -10,49 +10,67 @@ import { Component as LogsListTable } from "src/components/logs-list-table"; import { Component as LogsList } from "src/components/logs-list"; import { Component as ErrorComponent } from "src/components/error"; -export const DashboardLayout = ({ - abilities, - abilitiesBaseUrl, - abilitiesLoading, - abilitiesError, - logs, - logsLoading, - logsError, - AbilityCard -}) => { - return ( - - - - - - - - {logsError ? ( - {logsError.message} - ) : ( - - - - )} - - - - ); -}; +export class DashboardLayout extends Component { + constructor(props) { + super(props); + this.state = { + logsLoaded: props.logsLoading + }; + } + + componentDidUpdate() { + if (!this.state.logsLoaded && this.props.logsLoading === false) { + this.setState({ + logsLoaded: true + }); + } + } + + render() { + const { + abilities, + abilitiesBaseUrl, + abilitiesLoading, + abilitiesError, + logs, + logsLoading, + logsError, + AbilityCard + } = this.props; + return ( + + + + + + + + {logsError ? ( + {logsError.message} + ) : ( + + + + )} + + + + ); + } +} DashboardLayout.propTypes = { AbilityCard: PropTypes.func,