|
/** |
|
Tracks mission-related KPIs (goals) targets from daily notes. |
|
|
|
Daily notes' frontmatter structure: |
|
|
|
``` |
|
--- |
|
mission: |
|
220_01_332: |
|
water: 2000 |
|
sleep: 360 |
|
--- |
|
``` |
|
|
|
*/ |
|
class DvGoalsProgress { |
|
|
|
async getProgress(args, missions, days, folded) { |
|
const {dv} = args |
|
const foldSymbol = folded ? "-" : "+" |
|
let out = '> [!multi-column]\n' |
|
for (const nDays of days) { |
|
const header = nDays === 1 ? "Today's KPIs" : nDays + " Days KPIs" |
|
out = out + '>\n' |
|
out = out + '> > [!info]' + foldSymbol + ' ' + header + '\n> >\n' |
|
out = out + '> > |KPI|Daily Avg.|' + (nDays === 1 ? 'Target (Today) ' : 'Target (Day/Period)') + '|Progress|\n'; |
|
out = out + '> > |---|---|---|---|\n'; |
|
for (const mission of missions) { |
|
out = out + await this._getGoalsAverage(args, nDays, mission); |
|
} |
|
} |
|
dv.paragraph(out); |
|
} |
|
|
|
async _getGoalsAverage(args, nDays, mission) { |
|
const {app, dv, that} = args |
|
const missionId = mission.id |
|
const kpis = mission.kpis |
|
|
|
const columns = kpis.map(kpi => "round(sum(nonnull(rows.M." + kpi.name + ")) / " + nDays + ", 2) as \"" + kpi.name + "\"").join(", ") |
|
|
|
const dvQuery = ` |
|
TABLE WITHOUT ID |
|
` + columns + ` |
|
FROM #daily |
|
WHERE 1=1 |
|
AND date(today) - file.day < dur(` + nDays + ` days) |
|
FLATTEN mission["` + missionId + `"] AS M |
|
GROUP BY true |
|
` |
|
|
|
const qryAvg = await dv.query(dvQuery) |
|
|
|
let avgValues = qryAvg.value.values; |
|
let avgTable = []; |
|
|
|
for (let r of avgValues) { |
|
kpis.forEach(({goal, name, unit}, i) => { |
|
const avg = r[i]; |
|
const percentOfGoal = Math.round(avg * 100 / goal); |
|
let progressBar = '<progress value="' + percentOfGoal + '" max="100"></progress>' |
|
avgTable.push([name + " (" + unit + ")", avg, goal, percentOfGoal, progressBar]); |
|
}) |
|
} |
|
|
|
let out = ''; |
|
|
|
for (let r of avgTable) { |
|
let kpi = r[0]; |
|
let dailyAvg = r[1]; |
|
let dailyTarget = r[2]; |
|
let periodTarget = dailyTarget * nDays; |
|
let percent = r[3]; |
|
let bar = r[4]; |
|
|
|
out = out + '> > |' + kpi + '|' + dailyAvg + '|' + (nDays === 1 ? dailyTarget : dailyTarget + '/' + periodTarget) + '|' + bar + '|\n'; |
|
} |
|
|
|
return out |
|
} |
|
} |