refactor(metric): add action

This commit is contained in:
Johannes Millan 2025-10-10 15:06:28 +02:00
parent 394efb55e9
commit 56abbdda62
3 changed files with 52 additions and 30 deletions

View file

@ -6,6 +6,7 @@ import {
deleteMetric,
updateMetric,
upsertMetric,
logFocusSession,
} from './store/metric.actions';
import { combineLatest, Observable, of } from 'rxjs';
import { LineChartData, Metric, MetricState } from './metric.model';
@ -19,7 +20,7 @@ import {
selectSimpleCounterClickCounterLineChartData,
selectSimpleCounterStopWatchLineChartData,
} from './store/metric.selectors';
import { map, switchMap, take } from 'rxjs/operators';
import { map, switchMap } from 'rxjs/operators';
import { DEFAULT_METRIC_FOR_DAY } from './metric.const';
import {
selectCheckedImprovementIdsForDay,
@ -27,6 +28,8 @@ import {
} from './improvement/store/improvement.reducer';
import { DateService } from 'src/app/core/date/date.service';
const MIN_FOCUS_SESSION_DURATION = 1000;
@Injectable({
providedIn: 'root',
})
@ -116,37 +119,16 @@ export class MetricService {
}
logFocusSession(duration: number, day: string = this._dateService.todayStr()): void {
if (!duration || duration <= 0) {
if (!duration || duration < MIN_FOCUS_SESSION_DURATION) {
return;
}
this._store$
.pipe(select(selectMetricById, { id: day }), take(1))
.subscribe((metric) => {
if (metric) {
const focusSessions = metric.focusSessions ?? [];
this._store$.dispatch(
updateMetric({
metric: {
id: day,
changes: {
focusSessions: [...focusSessions, duration],
},
},
}),
);
} else {
this._store$.dispatch(
upsertMetric({
metric: {
id: day,
...DEFAULT_METRIC_FOR_DAY,
focusSessions: [duration],
},
}),
);
}
});
this._store$.dispatch(
logFocusSession({
day,
duration,
}),
);
}
// STATISTICS

View file

@ -7,6 +7,7 @@ enum MetricActionTypes {
'UpdateMetric' = '[Metric] Update Metric',
'UpsertMetric' = '[Metric] Upsert Metric',
'DeleteMetric' = '[Metric] Delete Metric',
'LogFocusSession' = '[Metric] Log Focus Session',
}
export const addMetric = createAction(
@ -28,3 +29,8 @@ export const deleteMetric = createAction(
MetricActionTypes.DeleteMetric,
props<{ id: string }>(),
);
export const logFocusSession = createAction(
MetricActionTypes.LogFocusSession,
props<{ day: string; duration: number }>(),
);

View file

@ -1,8 +1,15 @@
import { createEntityAdapter, EntityAdapter } from '@ngrx/entity';
import { addMetric, deleteMetric, updateMetric, upsertMetric } from './metric.actions';
import {
addMetric,
deleteMetric,
updateMetric,
upsertMetric,
logFocusSession,
} from './metric.actions';
import { Metric, MetricState } from '../metric.model';
import { loadAllData } from '../../../root-store/meta/load-all-data.action';
import { createReducer, on } from '@ngrx/store';
import { DEFAULT_METRIC_FOR_DAY } from '../metric.const';
export const METRIC_FEATURE_NAME = 'metric';
export const metricAdapter: EntityAdapter<Metric> = createEntityAdapter<Metric>();
@ -25,4 +32,31 @@ export const metricReducer = createReducer<MetricState>(
on(upsertMetric, (state, { metric }) => metricAdapter.upsertOne(metric, state)),
on(deleteMetric, (state, { id }) => metricAdapter.removeOne(id, state)),
on(logFocusSession, (state, { day, duration }) => {
if (duration <= 0) {
return state;
}
const existing = state.entities[day];
if (existing) {
const focusSessions = existing.focusSessions ?? [];
return metricAdapter.updateOne(
{
id: day,
changes: {
focusSessions: [...focusSessions, duration],
},
},
state,
);
}
const newMetric: Metric = {
id: day,
...DEFAULT_METRIC_FOR_DAY,
focusSessions: [duration],
};
return metricAdapter.upsertOne(newMetric, state);
}),
);