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.

177 lines
4.5 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <script lang="ts">
  2. import EmptyList from "../components/EmptyList.svelte";
  3. import EmptyParentEntry from "../components/EmptyParentEntry.svelte";
  4. import GoalEntry from "../components/GoalEntry.svelte";
  5. import LogEntry from "../components/LogEntry.svelte";
  6. import ParentEntry from "../components/ParentEntry.svelte";
  7. import ProjectEntry from "../components/ProjectEntry.svelte";
  8. import RefreshSelection from "../components/RefreshSelection.svelte";
  9. import type { ProjectResult } from "../models/project";
  10. import { fpGoalStore } from "../stores/goal";
  11. import { fpLogStore } from "../stores/logs";
  12. import { fpProjectStore, fpProjectStore2 } from "../stores/project";
  13. import { fpTaskStore } from "../stores/tasks";
  14. import { endOfDay, startOfDay } from "../utils/time";
  15. let fakeMap: {[projectId: string]: boolean} = {}
  16. let fakeProjects: ProjectResult[]
  17. let sortedProjects: ProjectResult[]
  18. $: {
  19. if ($fpGoalStore.stale && !$fpGoalStore.loading) {
  20. fpGoalStore.load({
  21. maxTime: new Date(Date.now() + (86400000 * 3)),
  22. minTime: new Date(),
  23. });
  24. }
  25. }
  26. $: {
  27. if ($fpTaskStore.stale && !$fpTaskStore.loading) {
  28. fpTaskStore.load({
  29. active: true,
  30. expiring: true,
  31. })
  32. }
  33. }
  34. $: {
  35. if ($fpProjectStore.stale && !$fpProjectStore.loading) {
  36. fpProjectStore.load({
  37. active: true,
  38. expiring: true,
  39. includeSemiActive: true,
  40. });
  41. }
  42. }
  43. $: {
  44. if ($fpProjectStore2.stale && !$fpProjectStore2.loading) {
  45. fpProjectStore2.load({
  46. favorite: true,
  47. });
  48. }
  49. }
  50. $: {
  51. if ($fpLogStore.stale && !$fpLogStore.loading) {
  52. fpLogStore.load({
  53. maxTime: endOfDay(new Date()),
  54. minTime: startOfDay(new Date()),
  55. })
  56. }
  57. }
  58. $: {
  59. const individualTasks = $fpTaskStore.tasks
  60. .filter(t => $fpProjectStore.projects.find(p => p.id === t.projectId) == null)
  61. .sort((a,b) => Date.parse(a.endTime) - Date.parse(b.endTime));
  62. fakeProjects = [];
  63. fakeMap = {};
  64. for (let task of individualTasks) {
  65. if (!task.project.active) {
  66. continue;
  67. }
  68. let fakeProject = fakeProjects.find(p => p.id === task.id);
  69. if (fakeProject == null) {
  70. fakeMap[task.projectId] = true;
  71. fakeProjects.push({
  72. ...task.project,
  73. tasks: [task],
  74. });
  75. } else {
  76. fakeProject.tasks.push(task);
  77. }
  78. }
  79. for (const fakeProject of fakeProjects) {
  80. fakeProject.createdTime = fakeProject.tasks.map(t => t.createdTime).sort()[0];
  81. fakeProject.endTime = fakeProject.tasks[0].endTime;
  82. }
  83. }
  84. $: {
  85. sortedProjects = [...fakeProjects, ...$fpProjectStore.projects]
  86. .sort((a,b) => Date.parse(a.endTime) - Date.parse(b.endTime));
  87. }
  88. </script>
  89. <div class="page">
  90. <div class="left">
  91. {#if !$fpGoalStore.loading || $fpGoalStore.goals.length > 0}
  92. <h1>Active Goals</h1>
  93. {/if}
  94. {#each $fpGoalStore.goals as goal (goal.id)}
  95. <GoalEntry goal={goal} />
  96. {/each}
  97. {#if !$fpGoalStore.loading && $fpGoalStore.goals.length === 0}
  98. <EmptyList icon="list" text="No goals." />
  99. {/if}
  100. {#if $fpLogStore.logs.length > 0}
  101. <h1>Today's Logs</h1>
  102. <EmptyParentEntry icon="list">
  103. {#each $fpLogStore.logs as log (log.id)}
  104. <LogEntry log={log} />
  105. {/each}
  106. </EmptyParentEntry>
  107. {/if}
  108. </div>
  109. <div class="right">
  110. {#if $fpProjectStore.projects.length > 0}
  111. <h1>Upcoming Deadlines</h1>
  112. {#each sortedProjects as project (project.id)}
  113. <ProjectEntry isFake={fakeMap[project.id]} hideInactive project={project} />
  114. {/each}
  115. {/if}
  116. {#if $fpProjectStore2.projects.length > 0}
  117. <h1>Starred Projects</h1>
  118. {#each $fpProjectStore2.projects as project (project.id)}
  119. <ProjectEntry hideInactive project={project} />
  120. {/each}
  121. {/if}
  122. </div>
  123. </div>
  124. <RefreshSelection />
  125. <style>
  126. div.page {
  127. display: flex;
  128. flex-direction: row;
  129. max-width: 100%;
  130. padding: 0 1ch;
  131. margin: 0;
  132. width: 1020px;
  133. box-sizing: border-box;
  134. margin: 1em auto;
  135. }
  136. div.left, div.right {
  137. width: 50%;
  138. padding: 0 1ch;
  139. margin: 0;
  140. box-sizing: border-box;
  141. }
  142. h1 {
  143. font-size: 1.5em;
  144. font-weight: 100;
  145. text-align: center;
  146. }
  147. @media screen and (max-width: 900px) {
  148. div.page {
  149. display: block;
  150. }
  151. div.left, div.right {
  152. padding-left: 0;
  153. padding-right: 0;
  154. padding-bottom: 2em;
  155. max-width: 100%;
  156. width: 640px;
  157. margin: auto;
  158. }
  159. }
  160. </style>