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.

112 lines
5.0 KiB

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