From 2ac8b5e7d90e0597e31c6eac0b9df9d23fe7cdc7 Mon Sep 17 00:00:00 2001 From: Erik Thorsell Date: Tue, 13 Jun 2023 06:57:12 +0200 Subject: [PATCH] Add ability to view yearly consumption The following three views are added: * Last Year: Show consumption for the previous year (YYYY-01-01 to YYYY-12-31) * This Year: Show consumption from the beginning of this year to today * Running Year: Show consumption for the past 365 days --- src/app/Graph/DataBoxes.tsx | 17 ++++++++++++++++- src/app/Graph/GraphLoader.lib.ts | 22 ++++++++++++++++++++++ src/app/Graph/GraphLoader.tsx | 20 +++++++++++++++++++- src/lib/config.ts | 5 ++++- src/lib/svk/thunks.ts | 25 +++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/app/Graph/DataBoxes.tsx b/src/app/Graph/DataBoxes.tsx index a00e539..d953881 100644 --- a/src/app/Graph/DataBoxes.tsx +++ b/src/app/Graph/DataBoxes.tsx @@ -120,6 +120,12 @@ const Consumed = function (props: { consumption: number; totalCost: number; dayC const renderPeriod = (p: config.PeriodTypes) => { switch (p) { + case 'last-year': + return förra året + case 'this-year': + return sedan 1a Januari i år + case 'running-year': + return sedan dagens datum förra året case 'last-month': return förra månaden case 'this-month': @@ -136,6 +142,15 @@ const Consumed = function (props: { consumption: number; totalCost: number; dayC onClick={() => { let p: config.PeriodTypes switch (configState.periodType) { + case 'last-year': + p = 'this-year' + break + case 'this-year': + p = 'running-year' + break + case 'running-year': + p = 'last-month' + break case 'last-month': p = 'rolling' if (new Date().getDate() === 1) { @@ -148,7 +163,7 @@ const Consumed = function (props: { consumption: number; totalCost: number; dayC p = 'rolling' break case 'rolling': - p = 'last-month' + p = 'last-year' break } dispatch(config.setPeriod(p)) diff --git a/src/app/Graph/GraphLoader.lib.ts b/src/app/Graph/GraphLoader.lib.ts index 858d632..0775997 100644 --- a/src/app/Graph/GraphLoader.lib.ts +++ b/src/app/Graph/GraphLoader.lib.ts @@ -25,3 +25,25 @@ export function getMonthIntervalFor(month: number): Period { return { from, to, hours } } + +export function getYearIntervalFor(year: number): Period { + const now = new Date() + now.setHours(0) + now.setMinutes(0) + now.setSeconds(0) + now.setMilliseconds(0) + + const from = new Date(year, 0, 1) + + let to: Date; + if (year < now.getFullYear()) { + to = new Date(year+1, 12, 31) // if year is last year, stop on New Year's eve + } else { + to = now // if year is this year, stop today + } + + const ms = to.getTime() - from.getTime() + const hours = Math.floor(ms / 1000 / 60 / 60) + + return { from, to, hours } +} diff --git a/src/app/Graph/GraphLoader.tsx b/src/app/Graph/GraphLoader.tsx index 014b8de..aaa1d5f 100644 --- a/src/app/Graph/GraphLoader.tsx +++ b/src/app/Graph/GraphLoader.tsx @@ -15,7 +15,7 @@ import { useDispatch, useSelector } from 'src/lib/hooks' import { push } from 'connected-react-router' import { DataSourceContext } from './Graphs' -import { getMonthIntervalFor } from './GraphLoader.lib' +import { getYearIntervalFor, getMonthIntervalFor } from './GraphLoader.lib' type Params = { id: string @@ -49,6 +49,24 @@ export default function GraphLoader(props: Props) { let after: Date | undefined = undefined const now = new Date() switch (configState.periodType) { + case 'last-year': { + let prevYear = now.getFullYear() - 1 + const period = getYearIntervalFor(prevYear) + after = period.from + first = period.hours + break + } + case 'this-year': { + let year = now.getFullYear() + const period = getYearIntervalFor(year) + after = period.from + first = period.hours + break + } + case 'running-year': { + last = last = 365 * 24 + break + } case 'last-month': { let prevMonth = now.getMonth() - 1 if (prevMonth < 0) prevMonth = 11 diff --git a/src/lib/config.ts b/src/lib/config.ts index 78eef8c..2778bcc 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -1,7 +1,7 @@ import { createAction, createSlice, PayloadAction } from '@reduxjs/toolkit' import { RootState } from './store' -export type PeriodTypes = 'last-month' | 'this-month' | 'rolling' +export type PeriodTypes = 'last-year' | 'this-year' | 'running-year' | 'last-month' | 'this-month' | 'rolling' export interface State { periodType: PeriodTypes beta: boolean @@ -14,6 +14,9 @@ const getInitialState = (): State => { const savedPeriod = localStorage.getItem('period') switch (savedPeriod) { + case 'last-year': + case 'this-year': + case 'running-year': case 'last-month': case 'this-month': case 'rolling': diff --git a/src/lib/svk/thunks.ts b/src/lib/svk/thunks.ts index db2437e..5ae1382 100644 --- a/src/lib/svk/thunks.ts +++ b/src/lib/svk/thunks.ts @@ -13,6 +13,31 @@ export const getProfile = createAsyncThunk { const YYMMDD = 'YYYY-MM-DD' switch (args.period) { + case 'last-year': { + const startLastYear = moment().startOf('year').subtract(1, 'year').date(1).hour(0).minute(0).second(0) + const endLastYear = moment(startLastYear) + .add(1, 'year') + .subtract(1, 'day') + .hour(0) + .minute(0) + .second(0) + return { + from: startLastYear.format(YYMMDD), + to: endLastYear.format(YYMMDD), + } + } + case 'this-year': + return { + from: moment().startOf('year').format(YYMMDD), + to: moment().format(YYMMDD), + } + case 'running-year': + return { + from: moment() + .subtract(365 * 24, 'hours') + .format(YYMMDD), + to: moment().format(YYMMDD), + } case 'last-month': { const startLastMonth = moment().subtract(1, 'month').date(1).hour(0).minute(0).second(0) const endLastMonth = moment(startLastMonth)