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.

158 lines
5.5 KiB

  1. <script lang="ts">
  2. import { navigate } from "svelte-routing";
  3. import stuffLogClient from "../clients/stufflog";
  4. import Checkbox from "../components/Checkbox.svelte";
  5. import DeadlineSelect from "../components/DeadlineSelect.svelte";
  6. import IconSelect from "../components/IconSelect.svelte";
  7. import Modal from "../components/Modal.svelte";
  8. import ProjectGroupSelect from "../components/ProjectGroupSelect.svelte";
  9. import StartTimeSelect from "../components/StartTimeSelect.svelte";
  10. import StatusTagSelect from "../components/StatusTagSelect.svelte";
  11. import { DEFAULT_ICON } from "../external/icons";
  12. import type { ProjectResult } from "../models/project";
  13. import markStale from "../stores/markStale";
  14. import modalStore from "../stores/modal";
  15. import { formatFormTime } from "../utils/time";
  16. export let deletion = false;
  17. export let creation = false;
  18. const md = $modalStore;
  19. let project: ProjectResult = {
  20. id: "",
  21. groupId: null,
  22. name: "",
  23. description: "",
  24. icon: DEFAULT_ICON,
  25. active: false,
  26. statusTag: "to do",
  27. createdTime: "",
  28. tasks: [],
  29. favorite: false,
  30. subtractAmount: 0,
  31. tags: [],
  32. }
  33. let verb = "Add";
  34. if (md.name === "project.edit" || md.name === "project.delete") {
  35. project = md.project;
  36. verb = (md.name === "project.edit") ? "Edit" : "Delete";
  37. } else if (md.name === "project.add") {
  38. project.groupId = md.groupId;
  39. } else {
  40. throw new Error("Wrong form")
  41. }
  42. let startTime = formatFormTime(project.startTime);
  43. let endTime = formatFormTime(project.endTime);
  44. let name = project.name;
  45. let description = project.description;
  46. let statusTag = project.statusTag || "";
  47. let icon = project.icon;
  48. let favorite = project.favorite;
  49. let subtractAmount = project.subtractAmount;
  50. let groupId = project.groupId || "";
  51. let error = null;
  52. let loading = false;
  53. let tags = project.tags.join(", ");
  54. function onSubmit() {
  55. loading = true;
  56. error = null;
  57. const iconChanged = icon !== project.icon;
  58. if (creation) {
  59. stuffLogClient.createProject({
  60. active: statusTag === "",
  61. groupId: groupId || void(0),
  62. startTime: ( startTime == "" ) ? null : new Date(startTime),
  63. endTime: ( endTime == "" ) ? null : new Date(endTime),
  64. statusTag: statusTag !== "" ? statusTag : null,
  65. subtractAmount: Math.min(subtractAmount, 0),
  66. tags: tags.length > 0 ? tags.split(",").map(t => t.trim()) : [],
  67. name, description, icon, favorite,
  68. }).then(newProject => {
  69. markStale("project", "task");
  70. modalStore.close();
  71. navigate(`/questlog/${newProject.groupId || "META_UNGROUPED"}/${newProject.id}`);
  72. }).catch(err => {
  73. error = err.message ? err.message : err.toString();
  74. }).finally(() => {
  75. loading = false;
  76. })
  77. } else if (deletion) {
  78. stuffLogClient.deleteProject(project.id).then(() => {
  79. markStale("project", "task");
  80. modalStore.close();
  81. }).catch(err => {
  82. error = err.message ? err.message : err.toString();
  83. }).finally(() => {
  84. loading = false;
  85. })
  86. } else {
  87. stuffLogClient.updateProject(project.id, {
  88. groupId: groupId || "",
  89. endTime: ( endTime == "" ) ? null : new Date(endTime),
  90. clearEndTime: ( endTime == "" ),
  91. startTime: ( startTime == "" ) ? null : new Date(startTime),
  92. clearStartTime: ( startTime == "" ),
  93. active: statusTag === "",
  94. statusTag: statusTag || null,
  95. clearStatusTag: statusTag === "",
  96. subtractAmount: subtractAmount,
  97. setTags: tags.length > 0 ? tags.split(",").map(t => t.trim()) : [],
  98. name, description, icon, favorite,
  99. }).then(() => {
  100. markStale("project", "task");
  101. if (iconChanged) {
  102. markStale("log");
  103. }
  104. modalStore.close();
  105. navigate(`/questlog/${groupId || "META_UNGROUPED"}/${project.id}`);
  106. }).catch(err => {
  107. error = err.message ? err.message : err.toString();
  108. }).finally(() => {
  109. loading = false;
  110. })
  111. }
  112. }
  113. function onClose() {
  114. modalStore.close();
  115. }
  116. </script>
  117. <Modal show title="{verb} Project" error={error} closable on:close={onClose}>
  118. <form on:submit|preventDefault={onSubmit}>
  119. <label for="group">Project Group</label>
  120. <ProjectGroupSelect optional name="group" disabled={deletion} bind:value={groupId} />
  121. <label for="name">Name</label>
  122. <input disabled={deletion} name="name" type="text" bind:value={name} />
  123. <label for="description">Description</label>
  124. <textarea disabled={deletion} name="description" bind:value={description} />
  125. <label for="itemId">Icon</label>
  126. <IconSelect disabled={deletion} bind:value={icon} />
  127. <label for="endTime">Deadline</label>
  128. <DeadlineSelect disabled={deletion} bind:value={endTime} />
  129. {#if endTime != ""}
  130. <label for="endTime">Start time</label>
  131. <StartTimeSelect disabled={deletion} bind:value={startTime} />
  132. <label for="subtractAmount">Subtract progress</label>
  133. <input disabled={deletion} name="subtractAmount" type="number" bind:value={subtractAmount} />
  134. {/if}
  135. <label for="statusTag">Status</label>
  136. <StatusTagSelect disabled={deletion} isProject bind:value={statusTag} />
  137. <label for="tags">Tags (Comma Separated)</label>
  138. <input disabled={deletion} name="tags" type="text" bind:value={tags} />
  139. <Checkbox disabled={deletion} bind:checked={favorite} label="Mark as favorite." />
  140. <hr />
  141. <button disabled={loading} type="submit">{verb} Project</button>
  142. </form>
  143. </Modal>