Skip to content
This repository has been archived by the owner on Mar 22, 2024. It is now read-only.

feat(stats): add aggregated statistics support #150

Merged
merged 1 commit into from
Mar 4, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
feat(stats): add aggregated statistics support
cberthou committed Mar 4, 2021
commit c0eec86c3bac6b9888ab95a4ad2e4bf355ba99e3
4 changes: 2 additions & 2 deletions src/display-data/statistics.ts
Original file line number Diff line number Diff line change
@@ -18,9 +18,9 @@ export const statisticsLayout: StatisticsGroup[] = [
size: 3,
statistics: [
{
fields: ["download", "appDownload"],
label: "téléchargements depuis la création",
type: "raw",
value: 15200,
type: "aggregated",
},
],
title: "Téléchargements",
15 changes: 8 additions & 7 deletions src/pages/statistiques.tsx
Original file line number Diff line number Diff line change
@@ -8,27 +8,28 @@ import SEO from "../components/seo";
import StatisticsGroup from "../components/statistics-group";
import { statisticsLayout } from "../display-data/statistics";
import Layout from "../layout";
import { Statistic } from "../types/statistic-types";
import { sanitizeStatistics } from "../utils/statistics-util";
import { StatisticsGroup as StatisticsGroupType } from "../types/statistic-types";
import { formatStatistics } from "../utils/statistics-util";

const minutesSinceTimestamp = (lastFetchTimestamp: number) => {
const timeDifference = Date.now() - lastFetchTimestamp;
return Math.floor(timeDifference / (60 * 1000));
};

const Statistiques = () => {
// eslint-disable-next-line no-unused-vars
const [statistics, setStatistics] = useState<Statistic[]>([]);
const [statistics, setStatistics] = useState<StatisticsGroupType[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [lastFetchTimestamp, setLastFetchTimestamp] = useState(0);

useEffect(() => {
const fetchStatistics = async () => {
// setIsLoading(true);
setIsLoading(true);
const fetchedStatistics = await axios
.get(`${process.env.STATISTICS_URL}/statistics`)
.then(({ data }) => data);
const sanitizedStatistics = sanitizeStatistics(fetchedStatistics.result);
const sanitizedStatistics = formatStatistics(statisticsLayout)(
fetchedStatistics.result
);
setLastFetchTimestamp(fetchedStatistics.lastFetchTimestamp);
setStatistics(sanitizedStatistics);
setIsLoading(false);
@@ -60,7 +61,7 @@ const Statistiques = () => {
</Box>
) : (
<Box>
{statisticsLayout.map((group, index) => (
{statistics.map((group, index) => (
<Box key={index} marginBottom={5}>
<StatisticsGroup group={group} />
</Box>
69 changes: 50 additions & 19 deletions src/utils/statistics-util.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// eslint-disable-next-line import/named
cberthou marked this conversation as resolved.
Show resolved Hide resolved
import { compose, map, sum } from "lodash/fp";

import { statisticsConfig } from "../display-data/statistics";
import {
AggregatedStatisticConfig,
isRawStatistic,
RawStatisticConfig,
SimpleStatisticConfig,
Statistic,
StatisticConfig,
StatisticsBlock,
StatisticsGroup,
} from "../types/statistic-types";

const findElementByLabel = (statistics: Statistic[], label: string) => {
@@ -16,7 +20,7 @@ const getValue = (statistic: Statistic) => statistic?.value || 0;

const findValueByLabel = compose(getValue, findElementByLabel);

const extractAggregatedStatisticProps = (
export const extractAggregatedStatisticProps = (
statistics: Statistic[],
configItem: AggregatedStatisticConfig
) =>
@@ -34,22 +38,49 @@ const isAggregatedStatistic = (
configItem: StatisticConfig
): configItem is AggregatedStatisticConfig => configItem.type === "aggregated";

const extractStatisticProps = (
statistics: Statistic[],
configItem: StatisticConfig
) =>
isAggregatedStatistic(configItem)
? extractAggregatedStatisticProps(statistics, configItem)
: extractSimpleStatisticProps(statistics, configItem);
const formatAggregatedStatistic = (statistic: AggregatedStatisticConfig) => (
data: Statistic[]
): RawStatisticConfig => ({
label: statistic.label,
type: "raw",
value: extractAggregatedStatisticProps(data, statistic),
});

const extractStatisticsProps = (
statistics: Statistic[],
config: StatisticConfig[]
) =>
config.map((configItem) => ({
label: configItem.label,
value: extractStatisticProps(statistics, configItem),
}));
const formatSimpleStatistic = (statistic: SimpleStatisticConfig) => (
data: Statistic[]
): RawStatisticConfig => ({
label: statistic.label,
type: "raw",
value: extractSimpleStatisticProps(data, statistic),
});

const formatStatistic = (statistic: StatisticConfig) => {
if (isAggregatedStatistic(statistic)) {
return formatAggregatedStatistic(statistic);
}

if (isRawStatistic(statistic)) {
return () => statistic;
}

return formatSimpleStatistic(statistic);
};

const formatBlock = (block: StatisticsBlock) => (
data: Statistic[]
): StatisticsBlock => ({
size: block.size,
statistics: block.statistics.map((stat) => formatStatistic(stat)(data)),
title: block.title,
});

const formatGroup = (group: StatisticsGroup) => (
data: Statistic[]
): StatisticsGroup => ({
blocks: group.blocks.map((block) => formatBlock(block)(data)),
title: group.title,
});

export const sanitizeStatistics = (statistics: Statistic[]) =>
extractStatisticsProps(statistics, statisticsConfig);
export const formatStatistics = (statisticsLayout: StatisticsGroup[]) => (
data: Statistic[]
) => statisticsLayout.map((group) => formatGroup(group)(data));