From 302bcd64147e1522d99fff4ccb2d8d1206a84235 Mon Sep 17 00:00:00 2001 From: Javier Brea Date: Mon, 25 Feb 2019 18:26:45 +0100 Subject: [PATCH] Add pagination to abilities logs --- mocks/features/fixtures/logs/get.js | 2 +- src/components/logs-list/LogsList.js | 2 +- src/components/paginated-list/index.js | 3 -- .../ScrollPaginatedList.js} | 29 ++++++++--- src/components/scroll-paginated-list/index.js | 3 ++ src/data-layer/services/logs/filters.js | 15 ------ src/data-layer/services/logs/origins.js | 10 +++- src/data-layer/services/logs/selectors.js | 50 +++++++++---------- .../abilities/components/ability/Ability.js | 35 ++++++++----- src/modules/abilities/views/Ability.js | 14 ++++-- src/modules/abilities/views/Logs.js | 19 +++++++ .../activity/components/activity/Activity.js | 28 ++--------- src/modules/dashboard/views/Main.js | 11 ++-- 13 files changed, 119 insertions(+), 102 deletions(-) delete mode 100644 src/components/paginated-list/index.js rename src/components/{paginated-list/PaginatedList.js => scroll-paginated-list/ScrollPaginatedList.js} (61%) create mode 100644 src/components/scroll-paginated-list/index.js delete mode 100644 src/data-layer/services/logs/filters.js create mode 100644 src/modules/abilities/views/Logs.js diff --git a/mocks/features/fixtures/logs/get.js b/mocks/features/fixtures/logs/get.js index fa71a88..5b04ee2 100644 --- a/mocks/features/fixtures/logs/get.js +++ b/mocks/features/fixtures/logs/get.js @@ -77,7 +77,7 @@ const getLogsSuccess = { }; const countLogsSuccess = { - url: "/api/logs/count", + url: "/api/logs/stats", method: "GET", response: { status: 200, diff --git a/src/components/logs-list/LogsList.js b/src/components/logs-list/LogsList.js index 2143d2c..ce553a4 100644 --- a/src/components/logs-list/LogsList.js +++ b/src/components/logs-list/LogsList.js @@ -40,7 +40,7 @@ export const LogsList = ({ logs = [], logsLoading, showPlaceHolders }) => { } return ( - {logs.length < 1 && !logsLoading ? : null} + {!showPlaceHolders && logs.length < 1 && !logsLoading ? : null} {logs.map(log => ( + + ); + } + if (!this.props.itemsCountLoading && this.props.itemsCount.total === 0) { + return ( + + + ); } return ( { - return logsResults.map(log => { - const ability = abilitiesResults.find(ability => ability._id === log._ability); - const service = servicesResults.find(service => service._id === ability._service); - return { - ...log, - dateTime: formatDate(log.createdAt), - module: (service && service.name) || "-", - ability: (ability && ability.name) || "-", - data: displayValue(log.data) - }; - }); -}; diff --git a/src/data-layer/services/logs/origins.js b/src/data-layer/services/logs/origins.js index 37d0bc9..7275f9d 100644 --- a/src/data-layer/services/logs/origins.js +++ b/src/data-layer/services/logs/origins.js @@ -12,7 +12,7 @@ export const logs = new origins.Api( ); export const countLogs = new origins.Api( - "/logs/count", + "/logs/stats", {}, { ...authConfig, @@ -21,3 +21,11 @@ export const countLogs = new origins.Api( } } ); + +countLogs.addCustomFilter({ + ofAbility: abilityId => ({ + query: { + ability: abilityId + } + }) +}); diff --git a/src/data-layer/services/logs/selectors.js b/src/data-layer/services/logs/selectors.js index 15811fd..6da0e5f 100644 --- a/src/data-layer/services/logs/selectors.js +++ b/src/data-layer/services/logs/selectors.js @@ -1,27 +1,25 @@ import { Selector } from "reactive-data-source"; +import { displayValue, formatDate } from "../../helpers"; + import { abilitiesCollection } from "../abilities/origins"; import { servicesCollection } from "../services/origins"; import { logs } from "./origins"; -import { addLogsDetails } from "./filters"; - -const NUMBER_OF_LOGS = 10; - -export const lastLogs = new Selector( - logs, - logsResults => [...logsResults].reverse().slice(0, NUMBER_OF_LOGS), - [] -); export const logsPage = new Selector( { source: logs, filter: filter => { + const query = {}; if (filter) { + if (filter.page) { + query.page = filter.page; + } + if (filter.ability) { + query.ability = filter.ability; + } return { - query: { - page: filter.page - } + query }; } return null; @@ -38,20 +36,18 @@ export const logsPageWithDetails = new Selector( source: logsPage, filter: filter => filter }, - addLogsDetails, - [] -); - -export const lastLogsDetails = new Selector( - abilitiesCollection, - servicesCollection, - lastLogs, - addLogsDetails, - [] -); - -export const logsOfAbility = new Selector( - lastLogsDetails, - (lastLogsResults, abilityId) => lastLogsResults.filter(log => log._ability === abilityId), + (abilitiesResults, servicesResults, logsResults) => { + return logsResults.map(log => { + const ability = abilitiesResults.find(ability => ability._id === log._ability); + const service = servicesResults.find(service => service._id === ability._service); + return { + ...log, + dateTime: formatDate(log.createdAt), + module: (service && service.name) || "-", + ability: (ability && ability.name) || "-", + data: displayValue(log.data) + }; + }); + }, [] ); diff --git a/src/modules/abilities/components/ability/Ability.js b/src/modules/abilities/components/ability/Ability.js index b99758a..c9c121e 100644 --- a/src/modules/abilities/components/ability/Ability.js +++ b/src/modules/abilities/components/ability/Ability.js @@ -3,8 +3,8 @@ import PropTypes from "prop-types"; import { Link } from "react-router-dom"; import { Component as Container } from "src/components/container-content"; +import { Component as ScrollPaginatedList } from "src/components/scroll-paginated-list"; import { Component as LogsListTable } from "src/components/logs-list-table"; -import { Component as LogsList } from "src/components/logs-list"; import { Component as Breadcrumbs } from "src/components/breadcrumbs"; import { Component as AbilityInfo } from "../ability-info"; import { Menu, Icon } from "semantic-ui-react"; @@ -13,27 +13,34 @@ const ACTIVITY = "activity"; const INFO = "info"; export const Ability = ({ - logs = [], - logsError, - logsLoading, + LogsList, + abilityId, ability = {}, abilityLoading, abilityError, display = INFO, activityUrl, infoUrl, - baseUrl + baseUrl, + logsPageSize, + logsCount, + logsCountLoading }) => { const subsection = display === ACTIVITY ? ( - - - + ) : ( ); - const loading = display === ACTIVITY ? logsLoading : abilityLoading; - const error = display === ACTIVITY ? logsError : abilityError; + const loading = display === ACTIVITY ? null : abilityLoading; + const error = display === ACTIVITY ? null : abilityError; return ( @@ -67,14 +74,16 @@ export const Ability = ({ }; Ability.propTypes = { + LogsList: PropTypes.func, ability: PropTypes.any.isRequired, abilityError: PropTypes.instanceOf(Error), + abilityId: PropTypes.string, abilityLoading: PropTypes.bool.isRequired, activityUrl: PropTypes.string, baseUrl: PropTypes.string, display: PropTypes.oneOf([ACTIVITY, INFO]), infoUrl: PropTypes.string, - logs: PropTypes.any.isRequired, - logsError: PropTypes.instanceOf(Error), - logsLoading: PropTypes.bool.isRequired + logsCount: PropTypes.any, + logsCountLoading: PropTypes.bool, + logsPageSize: PropTypes.number }; diff --git a/src/modules/abilities/views/Ability.js b/src/modules/abilities/views/Ability.js index 564e454..7a8f229 100644 --- a/src/modules/abilities/views/Ability.js +++ b/src/modules/abilities/views/Ability.js @@ -3,15 +3,19 @@ import { plugins } from "reactive-data-source"; import { Component as AbilityComponent } from "../components/ability"; import { abilityModelsWithExtraData } from "src/data-layer/services"; -import { logsOfAbility } from "src/data-layer/services"; +import { countLogs } from "src/data-layer/services"; + +import { Logs } from "./Logs"; export const mapDataSourceToProps = ({ id }) => { const ability = abilityModelsWithExtraData.byId(id).read; - const logs = logsOfAbility.filter(id).read; + const getLogsCount = countLogs.ofAbility(id).read.getters; return { - logs: logs.getters.value, - logsError: logs.getters.error, - logsLoading: logs.getters.loading, + LogsList: Logs, + logsPageSize: 10, + logsCount: getLogsCount.value, + logsCountLoading: getLogsCount.loading, + abilityId: id, ability: ability.getters.value, abilityError: ability.getters.error, abilityLoading: ability.getters.loading diff --git a/src/modules/abilities/views/Logs.js b/src/modules/abilities/views/Logs.js new file mode 100644 index 0000000..baa8312 --- /dev/null +++ b/src/modules/abilities/views/Logs.js @@ -0,0 +1,19 @@ +import { plugins } from "reactive-data-source"; + +import { Component as LogsList } from "src/components/logs-list"; + +import { logsPageWithDetails } from "src/data-layer/services"; + +export const mapDataSourceToProps = ({ page, extraFilter }) => { + const readLogs = logsPageWithDetails.filter({ + page: page, + ability: extraFilter.abilityId + }).read.getters; + return { + logs: readLogs.value, + error: readLogs.error, + logsLoading: readLogs.loading + }; +}; + +export const Logs = plugins.connect(mapDataSourceToProps)(LogsList); diff --git a/src/modules/activity/components/activity/Activity.js b/src/modules/activity/components/activity/Activity.js index 6181819..ed1e720 100644 --- a/src/modules/activity/components/activity/Activity.js +++ b/src/modules/activity/components/activity/Activity.js @@ -1,30 +1,10 @@ import React from "react"; import PropTypes from "prop-types"; -import { Component as PaginatedList } from "src/components/paginated-list"; +import { Component as ScrollPaginatedList } from "src/components/scroll-paginated-list"; import { Component as Container } from "src/components/container-content"; import { Component as Breadcrumbs } from "src/components/breadcrumbs"; - -import { Table } from "semantic-ui-react"; - -const ListWrapper = ({ children }) => ( - - - - At - Type - Module - Ability - Data - - - {children} -
-); - -ListWrapper.propTypes = { - children: PropTypes.node -}; +import { Component as LogsListTable } from "src/components/logs-list-table"; export const Activity = ({ LogsList, pageSize, logsCount, logsCountLoading }) => { return ( @@ -33,9 +13,9 @@ export const Activity = ({ LogsList, pageSize, logsCount, logsCountLoading }) =>
- { export const mapDataSourceToProps = () => { const abilities = dashboardAbilities.read; + const readlogsPage = logsPageWithDetails.filter({ + page: 1 + }).read.getters; return { abilities: abilities.getters.value, abilitiesError: abilities.getters.error, abilitiesLoading: abilities.getters.loading, - logs: lastLogsDetails.read.getters.value, - logsError: lastLogsDetails.read.getters.error, - logsLoading: lastLogsDetails.read.getters.loading, + logs: readlogsPage.value, + logsError: readlogsPage.error, + logsLoading: readlogsPage.loading, AbilityCard, abilitiesBaseUrl: config.abilitiesBaseUrl };