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.

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