Plan stuff. Log stuff.
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.

167 lines
5.1 KiB

4 years ago
  1. <script context="module">
  2. const UNKNOWN = (Object.freeze||(o => o))({
  3. name: "(Unknown)",
  4. subGoals: [],
  5. subActivities: [],
  6. });
  7. </script>
  8. <script>
  9. import { get } from "svelte/store";
  10. import pluralize from "pluralize";
  11. import Boi from "../components/Boi.svelte";
  12. import AddBoi from "../components/AddBoi.svelte";
  13. import Property from "../components/Property.svelte";
  14. import Row from "../components/Row.svelte";
  15. import Col from "../components/Col.svelte";
  16. import Link from "../components/Link.svelte";
  17. import ActivityIcon from "../components/ActivityIcon.svelte";
  18. import PointsBar from "../components/PointsBar.svelte";
  19. import stufflog from "../stores/stufflog";
  20. import modal from "../stores/modal";
  21. import dateStr from "../utils/dateStr";
  22. let activityMap = {};
  23. let scores = {};
  24. function openGoalModal(modalName, id, goalId, subGoalId) {
  25. const period = get(stufflog).periods.find(a => a.id === id);
  26. const goal = period ? period.goals.find(g => g.id === goalId) : null;
  27. const subGoal = goal ? goal.subGoals.find(s => s.id === subGoalId) : null;
  28. const activity = goal ? get(stufflog).activities.find(a => a.id === goal.activityId) : null
  29. modal.open(modalName, {period, goal, subGoal, activity})
  30. }
  31. function openLogModal(modalName, id, logId) {
  32. const period = get(stufflog).periods.find(a => a.id === id);
  33. const row = period ? period.table.find(r => r.log.id === logId) : {};
  34. modal.open(modalName, {period, ...row})
  35. }
  36. $: activityMap = $stufflog.activities.reduce((p, v) => ({...p, [v.id]: v}), {});
  37. </script>
  38. <div class="page">
  39. {#each $stufflog.periods as period (period.id)}
  40. <Boi header={period.name}>
  41. <Row>
  42. <Col size=3><Property label="From" value={dateStr(period.from)} /></Col>
  43. <Col size=3><Property label="To" value={dateStr(period.to)} /></Col>
  44. <Col size=6>
  45. <Property label="Options">
  46. <Link on:click={() => openGoalModal("period.edit", period.id)}>Edit Period</Link>,
  47. <Link on:click={() => openGoalModal("periodgoal.add", period.id)}>Add Goal</Link>,
  48. {#if period.goals.length > 0}
  49. <Link on:click={() => openGoalModal("periodlog.add", period.id)}>Add Log</Link>,
  50. {/if}
  51. <Link on:click={() => openGoalModal("period.delete", period.id)}>Delete Period</Link>
  52. </Property>
  53. </Col>
  54. </Row>
  55. <table>
  56. <tr>
  57. <th class="th-name">Activity</th>
  58. <th class="th-points">Points</th>
  59. <th class="th-options">Options</th>
  60. </tr>
  61. {#each period.goals as goal (goal.id)}
  62. <tr>
  63. <td>
  64. <div class="icon"><ActivityIcon name={(activityMap[goal.activityId] || {name: "(Unknown)"}).icon} /></div>
  65. <div class="name">{(activityMap[goal.activityId] || {name: "(Unknown)"}).name}</div>
  66. </td>
  67. <td><PointsBar value={period.scores[goal.id]} goal={goal.pointCount} /></td>
  68. <td class="td-options">
  69. <Link on:click={() => openGoalModal("periodgoal.remove", period.id, goal.id)}>Delete</Link>
  70. </td>
  71. </tr>
  72. {/each}
  73. </table>
  74. <table>
  75. <tr>
  76. <th class="th-date">Date</th>
  77. <th class="th-log">Goal</th>
  78. <th class="th-log">Sub-Activity</th>
  79. <th class="th-points2">Amount</th>
  80. <th class="th-points2">Points</th>
  81. <th class="th-options">Options</th>
  82. </tr>
  83. {#each period.table as row (row.log.id)}
  84. <tr>
  85. <td>{dateStr(row.log.date)}</td>
  86. <td class:dark={row.activity.name.startsWith("(")}>
  87. <div class="icon"><ActivityIcon name={row.activity.icon} /></div>
  88. <div class="name">{row.activity.name} {row.subActivity.name}</div>
  89. </td>
  90. <td class:dark={row.subGoal.name.startsWith("(")}>{row.subGoal.name}</td>
  91. <td>{row.log.amount} {pluralize(row.subActivity.unitName, row.log.amount)}</td>
  92. <td>
  93. <Link on:click={() => openLogModal("periodlog.info", period.id, row.log.id)}>{row.log.score.total}</Link>
  94. </td>
  95. <td class="td-options">
  96. <Link on:click={() => openLogModal("periodlog.remove", period.id, row.log.id)}>Delete</Link>
  97. </td>
  98. </tr>
  99. {/each}
  100. </table>
  101. </Boi>
  102. {/each}
  103. <AddBoi on:click={() => modal.open("period.create")}>Period</AddBoi>
  104. </div>
  105. <style>
  106. div.page {
  107. width: 100ch;
  108. max-width: 90%;
  109. margin: auto;
  110. }
  111. table {
  112. width: 100%;
  113. padding: 0.5em 0;
  114. }
  115. table th, table td {
  116. padding: 0em 1ch;
  117. }
  118. table th {
  119. text-align: left;
  120. font-size: 0.75em;
  121. }
  122. table th.th-name {
  123. width: 25%;
  124. }
  125. table th.th-date {
  126. width: 25%;
  127. }
  128. table th.th-points {
  129. width: 62.5%;
  130. }
  131. table th.th-options, table td.td-options {
  132. width: 12.5%;
  133. text-align: right;
  134. }
  135. table th.th-log {
  136. width: calc(37.5%/2);
  137. }
  138. table th.th-points2 {
  139. width: 12.5%;
  140. }
  141. table td.dark {
  142. color: #666;
  143. }
  144. table td div.icon {
  145. position: relative;
  146. top: 0.175em;
  147. display: inline-block;
  148. }
  149. table td div.name {
  150. display: inline-block;
  151. }
  152. </style>