Skip to content

Commit

Permalink
refactor(eventsSlice): replace useWeightsInPeriod with a new events…
Browse files Browse the repository at this point in the history
…Slice selector
  • Loading branch information
benji6 committed Dec 28, 2023
1 parent 643aa71 commit 9abf55c
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 23 deletions.
8 changes: 0 additions & 8 deletions client/src/components/hooks/useWeightsInPeriod.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import {
} from "../../../../utils";
import MoodSummary from "../../../shared/MoodSummary";
import { Paper } from "eri";
import { RootState } from "../../../../store";
import eventsSlice from "../../../../store/eventsSlice";
import useMoodsInPeriod from "../../../hooks/useMoodsInPeriod";
import { useSelector } from "react-redux";
import useWeightsInPeriod from "../../../hooks/useWeightsInPeriod";

interface Props {
dateFrom: Date;
Expand All @@ -18,8 +18,8 @@ interface Props {
export default function MoodSummaryForPeriod({ dateFrom, dateTo }: Props) {
const meditations = useSelector(eventsSlice.selectors.normalizedMeditations);
const moodValues = useMoodsInPeriod(dateFrom, dateTo).map(({ mood }) => mood);
const weightsInPeriod = useWeightsInPeriod(dateFrom, dateTo).map(
({ value }) => value,
const meanWeightInPeriod = useSelector((state: RootState) =>
eventsSlice.selectors.meanWeightInPeriod(state, dateFrom, dateTo),
);
const secondsMeditated = computeSecondsMeditatedInInterval(
meditations,
Expand All @@ -30,14 +30,16 @@ export default function MoodSummaryForPeriod({ dateFrom, dateTo }: Props) {
return (
<Paper>
<h3>Summary</h3>
{!moodValues.length && !moodValues.length && !weightsInPeriod.length && (
<p>No data for the selected period</p>
)}
{!moodValues.length &&
!moodValues.length &&
meanWeightInPeriod === undefined && (
<p>No data for the selected period</p>
)}
<MoodSummary
currentPeriod={{
best: moodValues.length ? Math.max(...moodValues) : undefined,
mean: computeMeanSafe(moodValues),
meanWeight: computeMeanSafe(weightsInPeriod),
meanWeight: meanWeightInPeriod,
secondsMeditated,
standardDeviation: computeStandardDeviation(moodValues),
total: moodValues.length,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import {
computeMeanSafe,
computeSecondsMeditatedInInterval,
computeStandardDeviation,
formatIsoDateInLocalTimezone,
} from "../../../utils";
import MoodSummary from "../../shared/MoodSummary";
import { Paper } from "eri";
import { RootState } from "../../../store";
import eventsSlice from "../../../store/eventsSlice";
import useMoodsInPeriod from "../../hooks/useMoodsInPeriod";
import { useSelector } from "react-redux";
import useWeightsInPeriod from "../../hooks/useWeightsInPeriod";

interface Props {
dates: [Date, Date, Date];
Expand All @@ -29,11 +28,11 @@ export default function MoodSummaryForCalendarPeriod({
}: Props) {
const meditations = useSelector(eventsSlice.selectors.normalizedMeditations);
const moods = useSelector(eventsSlice.selectors.normalizedMoods);
const weightsInPeriod = useWeightsInPeriod(date1, date2).map(
({ value }) => value,
const meanWeightInPeriod = useSelector((state: RootState) =>
eventsSlice.selectors.meanWeightInPeriod(state, date1, date2),
);
const weightsInPreviousPeriod = useWeightsInPeriod(date0, date1).map(
({ value }) => value,
const meanWeightInPreviousPeriod = useSelector((state: RootState) =>
eventsSlice.selectors.meanWeightInPeriod(state, date0, date1),
);

const firstMoodDate = new Date(moods.allIds[0]);
Expand All @@ -49,7 +48,7 @@ export default function MoodSummaryForCalendarPeriod({
currentPeriod={{
best: moodValues.length ? Math.max(...moodValues) : undefined,
mean: normalizedAverages.byId[formatIsoDateInLocalTimezone(date1)],
meanWeight: computeMeanSafe(weightsInPeriod),
meanWeight: meanWeightInPeriod,
secondsMeditated: computeSecondsMeditatedInInterval(
meditations,
date1,
Expand All @@ -69,7 +68,7 @@ export default function MoodSummaryForCalendarPeriod({
mean: normalizedAverages.byId[
formatIsoDateInLocalTimezone(date0)
],
meanWeight: computeMeanSafe(weightsInPreviousPeriod),
meanWeight: meanWeightInPreviousPeriod,
secondsMeditated: computeSecondsMeditatedInInterval(
meditations,
date0,
Expand Down
72 changes: 72 additions & 0 deletions client/src/store/eventsSlice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,78 @@ describe("eventsSlice", () => {
).toEqual(["🙂", "Bulbasaur", "Charmander", "Pikachu", "Squirtle"]);
});

describe("meanWeightInPeriod", () => {
test("when there are no events", () => {
expect(
eventsSlice.selectors.meanWeightInPeriod(
initialState,
new Date("2020-01-01"),
new Date("2023-01-01"),
),
).toBe(undefined);
});

test("when there are no events that match the date range", () => {
expect(
eventsSlice.selectors.meanWeightInPeriod(
{
...initialState,
events: {
...initialState.events,
allIds: ["2020-01-01T00:00:00.000Z"],
byId: {
"2020-01-01T00:00:00.000Z": {
createdAt: "2020-01-01T00:00:00.000Z",
type: "v1/weights/create",
payload: { value: 70 },
},
},
},
},
new Date("2020-01-02"),
new Date("2023-01-01"),
),
).toBe(undefined);
});

test("when there are events that match the date range", () => {
expect(
eventsSlice.selectors.meanWeightInPeriod(
{
...initialState,
events: {
...initialState.events,
allIds: [
"2020-01-01T00:00:00.000Z",
"2020-01-02T00:00:00.000Z",
"2020-01-03T00:00:00.000Z",
],
byId: {
"2020-01-01T00:00:00.000Z": {
createdAt: "2020-01-01T00:00:00.000Z",
type: "v1/weights/create",
payload: { value: 10 },
},
"2020-01-02T00:00:00.000Z": {
createdAt: "2020-01-02T00:00:00.000Z",
type: "v1/weights/create",
payload: { value: 50 },
},
"2020-01-03T00:00:00.000Z": {
createdAt: "2020-01-03T00:00:00.000Z",
type: "v1/weights/create",
payload: { value: 70 },
},
},
},
},
new Date("2020-01-02"),
new Date("2023-01-01"),
),
).toBe(60);
});
});

describe("moodIdsByDate", () => {
test("when there are no events", () => {
expect(eventsSlice.selectors.moodIdsByDate(initialState)).toEqual({});
Expand Down
14 changes: 14 additions & 0 deletions client/src/store/eventsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ import {
import { PayloadAction, createSelector, createSlice } from "@reduxjs/toolkit";
import {
computeAverageMoodInInterval,
computeMeanSafe,
computeSecondsMeditatedInInterval,
formatIsoDateHourInLocalTimezone,
formatIsoDateInLocalTimezone,
getIdsInInterval,
getNormalizedTagsFromDescription,
} from "../utils";
import { WEEK_OPTIONS } from "../formatters/dateTimeFormatters";
Expand Down Expand Up @@ -359,6 +361,18 @@ export default createSlice({
normalizedStateNotEmpty,
),

meanWeightInPeriod: createSelector(
normalizedWeightsSelector,
(_state, dateFrom: Date) => dateFrom,
(_state, _dateFrom: Date, dateTo: Date) => dateTo,
({ allIds, byId }, dateFrom: Date, dateTo: Date) =>
computeMeanSafe(
getIdsInInterval(allIds, dateFrom, dateTo)
.map((id) => byId[id])
.map(({ value }) => value),
),
),

// some code may depend on the fact that the array
// value in the returned object cannot be empty
moodIdsByDate: createSelector(
Expand Down

0 comments on commit 9abf55c

Please sign in to comment.