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.

166 lines
5.5 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. <script lang="ts">
  2. import stuffLogClient from "../clients/stufflog";
  3. import type { ProjectResult, ProjectUpdate } from "../models/project";
  4. import type { TaskResult } from "../models/task";
  5. import markStale from "../stores/markStale";
  6. import type { ModalData } from "../stores/modal";
  7. import IS_MOBILE from "../utils/phone-check";
  8. import Icon from "./Icon.svelte";
  9. import ItemProgress from "./ItemProgress.svelte";
  10. import Option from "./Option.svelte";
  11. import OptionRow from "./OptionRow.svelte";
  12. import ParentEntry from "./ParentEntry.svelte";
  13. import ProgressNumbers from "./ProgressNumbers.svelte";
  14. import StatusColor from "./StatusColor.svelte";
  15. import TagList from "./TagList.svelte";
  16. import TaskList from "./TaskList.svelte";
  17. export let project: ProjectResult = null;
  18. export let showAllOptions: boolean = false;
  19. export let hideInactive: boolean = false;
  20. export let hideProgress: boolean = false;
  21. export let linkProject: boolean = false;
  22. export let hideIcon: boolean = false;
  23. export let isFake: boolean = false;
  24. export let removeHook: boolean = false;
  25. let mdAddTask: ModalData;
  26. let mdProjectEdit: ModalData;
  27. let mdProjectDelete: ModalData;
  28. let mdLinkTask: ModalData;
  29. let linkTarget: string = "";
  30. let activeTasks: TaskResult[] = [];
  31. let inactiveTasks: TaskResult[] = [];
  32. let todoTasks: TaskResult[] = [];
  33. let completedTasks: TaskResult[] = [];
  34. let onholdTasks: TaskResult[] = [];
  35. let failedTasks: TaskResult[] = [];
  36. let nonHiddenTasks: TaskResult[] = [];
  37. let toggling = false;
  38. let canComplete = false;
  39. function updateProject(update: ProjectUpdate) {
  40. if (toggling) {
  41. return
  42. }
  43. toggling = true
  44. stuffLogClient.updateProject(project.id, {...update}).then(() => {
  45. markStale("project");
  46. }).catch(err => {
  47. console.warn("Failed to toggle favorite:", err);
  48. }).finally(() => {
  49. toggling = false;
  50. })
  51. }
  52. function toggleFavorite() {
  53. updateProject({
  54. favorite: !project.favorite,
  55. });
  56. }
  57. function markCompleted() {
  58. updateProject({
  59. statusTag: "completed",
  60. active: false,
  61. })
  62. }
  63. function markFailed() {
  64. updateProject({
  65. statusTag: "failed",
  66. active: false,
  67. })
  68. }
  69. $: mdAddTask = {name:"task.add", project};
  70. $: mdLinkTask = {name:"tasklink.add", project};
  71. $: mdProjectEdit = {name:"project.edit", project};
  72. $: mdProjectDelete = {name:"project.delete", project};
  73. $: {
  74. activeTasks = project.tasks.filter(t => t.active);
  75. inactiveTasks = project.tasks.filter(t => !t.active);
  76. todoTasks = inactiveTasks.filter(t => t.statusTag === "to do" || t.statusTag === "idea");
  77. onholdTasks = inactiveTasks.filter(t => t.statusTag === "on hold");
  78. completedTasks = inactiveTasks.filter(t => t.statusTag === "completed" || t.statusTag == null);
  79. failedTasks = inactiveTasks.filter(t => t.statusTag === "failed" || t.statusTag === "declined");
  80. nonHiddenTasks = [...activeTasks, ...todoTasks, ...onholdTasks];
  81. }
  82. $: canComplete = project.active && completedTasks.length + failedTasks.length === project.tasks.length;
  83. $: linkTarget = IS_MOBILE ? `/projects#${project.id}` : `/questlog#${project.id}`
  84. </script>
  85. <StatusColor affects="project" entry={project}>
  86. <ParentEntry
  87. full={showAllOptions}
  88. entry={project}
  89. headerLink={linkProject ? linkTarget : ""}
  90. hideProgress={hideProgress}
  91. hideIcon={hideIcon}
  92. showTimeProgress={!hideProgress}
  93. removeHook={removeHook}
  94. >
  95. <div slot="pre-annotation" class="favorite" class:enabled={project.favorite} class:toggling on:click={toggleFavorite}>
  96. {#if !isFake}
  97. <Icon block name="star" />
  98. {/if}
  99. </div>
  100. <div slot="post-seprator">
  101. <ProgressNumbers project={project} />
  102. </div>
  103. <div slot="above-description">
  104. {#if showAllOptions}
  105. <TagList tags={project.tags} />
  106. {/if}
  107. </div>
  108. {#if showAllOptions}
  109. <ItemProgress project={project} vertical />
  110. <OptionRow>
  111. <Option open={mdAddTask}>Add Task</Option>
  112. <Option open={mdLinkTask}>Link Task</Option>
  113. <Option open={mdProjectEdit}>Edit</Option>
  114. <Option open={mdProjectDelete}>Delete</Option>
  115. {#if canComplete}
  116. <Option disabled={!toggling} color="green" on:click={markCompleted}>Complete Project</Option>
  117. <Option disabled={!toggling} color="red" on:click={markFailed}>Fail Project</Option>
  118. {/if}
  119. </OptionRow>
  120. {/if}
  121. {#if project.taskSortFields.length > 0 && !project.taskSortFields[0].includes("status")}
  122. <TaskList header="" tasks={project.tasks} project={project} showAllOptions={showAllOptions} />
  123. {:else if hideInactive}
  124. <TaskList header="" tasks={nonHiddenTasks} project={project} showAllOptions={showAllOptions} />
  125. {:else}
  126. <TaskList header="Active" tasks={activeTasks} project={project} showAllOptions={showAllOptions} />
  127. <TaskList header="To Do" tasks={todoTasks} project={project} showAllOptions={showAllOptions} />
  128. <TaskList header="On Hold" tasks={onholdTasks} project={project} showAllOptions={showAllOptions} />
  129. <TaskList header="Completed" tasks={completedTasks} project={project} showAllOptions={showAllOptions} />
  130. <TaskList header="Failed" tasks={failedTasks} project={project} showAllOptions={showAllOptions} />
  131. {/if}
  132. </ParentEntry>
  133. </StatusColor>
  134. <style>
  135. div.favorite {
  136. margin: auto 0;
  137. padding: 0 0.5ch;
  138. line-height: 0em;
  139. color: #333;
  140. cursor: pointer;
  141. }
  142. div.favorite.enabled {
  143. color: #e7e55e
  144. }
  145. div.favorite.toggling {
  146. opacity: 0.5;
  147. }
  148. </style>