You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
4.3 KiB
180 lines
4.3 KiB
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 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),
|
|
}));
|
|
|
|
return data;
|
|
}
|
|
|
|
function replacePeriod(d, period) {
|
|
return {
|
|
...d,
|
|
periods: [
|
|
...d.periods.filter(a => a.id !== period.id),
|
|
{
|
|
...period,
|
|
scores: calculateTotalScore(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),
|
|
})),
|
|
}));
|
|
},
|
|
|
|
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),
|
|
})),
|
|
}));
|
|
},
|
|
|
|
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;
|