|
|
import { writable, derived } from "svelte/store";
import slApi from "../api/stufflog"; import Activity, { ActivityUpdate } from "../models/activity"; import Period, { PeriodUpdate } from "../models/period";
const UNKNOWN_GOAL = Object.freeze({name: "(Unknown)", subGoals: []}); const NO_SUB_GOAL = Object.freeze({name: "(None)"}); const UNKNOWN_SUB_GOAL = Object.freeze({name: "(Unknown)"}); const UNKNOWN_ACTIVITY = Object.freeze({name: "(Unknown)", subActivities: []}); const UNKNOWN_SUB_ACTIVITY = Object.freeze({name: "(Unknown)", unitName: "unit"});
function calculateTotalScore(period) { return period.goals.reduce((o, g) => o = ({...o, [g.id]: ( period.logs.filter(l => l.goalId === g.id) .map(l => l.score.total) .reduce((n, m) => n + m, 0) )}), {}) }
function generateLogTable(activities, period) { const newTable = [];
for (const log of period.logs) { const goal = period.goals.find(g => g.id === log.goalId) || UNKNOWN_GOAL; const subGoal = log.subGoalId ? goal.subGoals.find(s => s.id === log.subGoalId) || UNKNOWN_SUB_GOAL : NO_SUB_GOAL; const activity = activities.find(a => a.id === goal.activityId) || UNKNOWN_ACTIVITY; const subActivity = activity.subActivities.find(s => s.id === log.subActivityId) || UNKNOWN_SUB_ACTIVITY;
newTable.push({log, goal, subGoal, activity, subActivity}) }
newTable.sort((a, b) => a.log.date - b.log.date);
return newTable; }
function replaceActivity(d, activity) { const data = { ...d, activities: [ ...d.activities.filter(a => a.id !== activity.id), activity, ].sort((a,b) => a.name.localeCompare(b.name)), };
data.periods = data.periods.map(p => ({ ...p, scores: calculateTotalScore(p), table: generateLogTable(data.activities, p), }));
return data; }
function replacePeriod(d, period) { return { ...d, periods: [ ...d.periods.filter(a => a.id !== period.id), { ...period, scores: calculateTotalScore(period), table: generateLogTable(d.activities, period), }, ].sort((a,b) => b.from - a.from), }; }
function deleteActivity(d, id) { return { ...d, activities: d.activities.filter(a => a.id !== id), }; }
function deletePeriod(d, id) { return { ...d, periods: d.periods.filter(a => a.id !== id), }; }
function createStufflogStore() { /** @type {{activities: Activity[], periods: Period[], logTables: {}}} */ const initialData = {activities: [], periods: [], logTables: {}};
const {set, update, subscribe} = writable(initialData);
return { subscribe,
async listActivities() { const activities = await slApi.listActivities(); update(d => ({ ...d, activities: activities.sort((a,b) => a.name.localeCompare(b.name)), periods: d.periods.map(p => ({ ...p, scores: calculateTotalScore(p), table: generateLogTable(activities, p), })), })); },
async loadActivity(id) { const activity = await slApi.findActivity(id); update(d => replaceActivity(d, activity)); },
async listPeriods() { const periods = await slApi.listPeriods(); update(d => ({ ...d, periods: periods.sort((a,b) => b.from - a.from).map(p => ({ ...p, scores: calculateTotalScore(p), table: generateLogTable(d.activities, p), })), })); },
async loadPeriods(id) { const period = await slApi.findPeriod(id); update(d => replacePeriod(d, period)); },
/** * Create period * * @param {Period} input */ async createPeriod(input) { const period = await slApi.postPeriod(input); update(d => replacePeriod(d, period)); },
/** * Create an activity * * @param {Activity} input */ async createActivity(input) { const activity = await slApi.postActivity(input); update(d => replaceActivity(d, activity)) },
/** * Update activities * * @param {string} id * @param {...ActivityUpdate} updates */ async updateActivity(id, ...updates) { const activity = await slApi.patchActivity(id, ...updates); update(d => replaceActivity(d, activity)); },
/** * Update periods * * @param {string} id * @param {...PeriodUpdate} updates */ async updatePeriod(id, ...updates) { const period = await slApi.patchPeriod(id, ...updates); update(d => replacePeriod(d, period)); },
/** * Delete an activity * * @param {string} id */ async deleteActivity(id) { const activity = await slApi.deleteActivity(id); update(d => deleteActivity(d, activity.id)); },
/** * Delete a period * * @param {string} id */ async deletePeriod(id) { const period = await slApi.deletePeriod(id); update(d => deletePeriod(d, period.id)); },
/** * Clear all data. This does not do any API call. */ clearAll() { set({activities: [], periods: []}); }, } };
const stufflog = createStufflogStore();
export default stufflog;
|