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.

121 lines
5.1 KiB

  1. <script lang="ts" context="module">
  2. let lastQuest = "";
  3. </script>
  4. <script lang="ts">
  5. import type { ProjectResult } from "../models/project";
  6. import selectionStore from "../stores/selection";
  7. import ProjectEntry from "./ProjectEntry.svelte";
  8. import QlList from "./QLList.svelte";
  9. import Boi from "../components/Boi.svelte";
  10. import type { ModalData } from "../stores/modal";
  11. import type { ProjectGroupResult } from "../models/projectgroup";
  12. import ProjectGroupMenu from "./ProjectGroupMenu.svelte";
  13. import OptionRow from "./OptionRow.svelte";
  14. import Option from "./Option.svelte";
  15. import type ProjectGroup from "../models/projectgroup";
  16. export let groups: ProjectGroupResult[];
  17. export let projectId = "";
  18. export let groupId = "";
  19. let mdProjectAdd: ModalData = {name: "project.add", groupId: null};
  20. let mdGroupEdit: ModalData = {name: "projectgroup.edit", projectGroup: {} as ProjectGroup};
  21. let mdGroupDelete: ModalData = {name: "projectgroup.delete", projectGroup: {} as ProjectGroup};
  22. let projects: ProjectResult[] = [];
  23. let expiringProjects: ProjectResult[];
  24. let activeProjects: ProjectResult[];
  25. let inactiveProjects: ProjectResult[];
  26. let completedProjects: ProjectResult[];
  27. let failedProjects: ProjectResult[];
  28. let onholdProjects: ProjectResult[];
  29. let ideaProjects: ProjectResult[];
  30. let project: ProjectResult = null;
  31. let selectedGroup: ProjectGroupResult | null = null;
  32. function sortProjects(a: ProjectResult, b: ProjectResult) {
  33. const aName = `${a.tags.slice(0, 1).map(t => t+":").join("")} ${a.name}`.trim();
  34. const bName = `${b.tags.slice(0, 1).map(t => t+":").join("")} ${b.name}`.trim();
  35. return aName.localeCompare(bName);
  36. }
  37. // Ensure a selection.
  38. $: {
  39. if (groupId == "" && groups.length > 0) {
  40. groupId = groups[0].id;
  41. }
  42. }
  43. $: selectedGroup = groups.find(g => g.id === groupId)
  44. $: projects = selectedGroup?.projects || [];
  45. $: mdProjectAdd = { name: "project.add", groupId: groupId }
  46. $: mdGroupEdit = { name: "projectgroup.edit", projectGroup: selectedGroup }
  47. $: mdGroupDelete = { name: "projectgroup.delete", projectGroup: selectedGroup }
  48. $: project = $selectionStore.hash.startsWith("P") ? projects.find(p => p.id === $selectionStore.hash) : null;
  49. $: expiringProjects = projects.filter(p => p.active && p.endTime).sort((a,b) => Date.parse(a.endTime) - Date.parse(b.endTime));
  50. $: activeProjects = projects.filter(p => p.active && !p.endTime).sort(sortProjects);
  51. $: inactiveProjects = projects.filter(p => !p.active).sort(sortProjects);
  52. $: completedProjects = inactiveProjects.filter(p => p.statusTag === "completed" || p.statusTag == null);
  53. $: failedProjects = inactiveProjects.filter(p => p.statusTag === "failed" || p.statusTag === "declined");
  54. $: onholdProjects = inactiveProjects.filter(p => p.statusTag === "on hold" || p.statusTag === "onhold").sort(sortProjects);
  55. $: ideaProjects = inactiveProjects.filter(p => p.statusTag === "to do" || p.statusTag === "idea").sort(sortProjects);
  56. $: backgroundProjects = inactiveProjects.filter(p => p.statusTag === "background").sort(sortProjects);
  57. $: progressProjects = inactiveProjects.filter(p => p.statusTag === "progress").sort(sortProjects);
  58. $: project = selectedGroup?.projects.find(p => p.id === projectId) || null;
  59. </script>
  60. <ProjectGroupMenu selected={groupId} groups={groups} />
  61. <div class="quest-log">
  62. <div class="list">
  63. <h2>{selectedGroup?.name || ""}</h2>
  64. {#if !!groupId && groupId !== "META_UNGROUPED"}
  65. <OptionRow centered>
  66. <Option open={mdGroupEdit}>Edit Group</Option>
  67. <Option open={mdGroupDelete}>Delete Group</Option>
  68. </OptionRow>
  69. {/if}
  70. <Boi compacter open={mdProjectAdd}>Add Project</Boi>
  71. <QlList selected={project?.id} label={selectedGroup?.categoryNames["deadlines"] || "Deadlines"} projects={expiringProjects} />
  72. <QlList selected={project?.id} label={selectedGroup?.categoryNames["active"] || "Active"} projects={activeProjects} />
  73. <QlList selected={project?.id} label={selectedGroup?.categoryNames["background"] || "Background"} projects={backgroundProjects} />
  74. <QlList selected={project?.id} label={selectedGroup?.categoryNames["progress"] || "Progress"} projects={progressProjects} />
  75. <QlList selected={project?.id} label={selectedGroup?.categoryNames["to do"] || "To Do"} projects={ideaProjects} />
  76. <QlList selected={project?.id} label={selectedGroup?.categoryNames["on hold"] || "On Hold"} projects={onholdProjects} />
  77. <QlList selected={project?.id} label={selectedGroup?.categoryNames["completed"] || "Completed"} projects={completedProjects} />
  78. <QlList selected={project?.id} label={selectedGroup?.categoryNames["failed"] || "Failed"} projects={failedProjects} />
  79. </div>
  80. <div class="body">
  81. {#if project != null}
  82. <ProjectEntry removeHook hideIcon project={project} showAllOptions />
  83. {/if}
  84. </div>
  85. </div>
  86. <style>
  87. div.quest-log {
  88. display: flex;
  89. flex-direction: row;
  90. }
  91. div.list {
  92. flex-shrink: 0;
  93. width: 32ch;
  94. }
  95. h2 {
  96. font-weight: 200;
  97. margin: 0;
  98. padding-bottom: 0.2em;
  99. text-align: center;
  100. }
  101. div.body {
  102. flex-grow: 1;
  103. margin: 1em 1ch;
  104. }
  105. </style>