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.

98 lines
2.9 KiB

  1. <script lang="ts">
  2. import type Project from "../models/project";
  3. import projectStore from "../stores/project";
  4. import projectGroupStore from "../stores/projectGroup";
  5. interface OptGroup {
  6. status: string
  7. projects: Project[]
  8. }
  9. export let value = "";
  10. export let name = "";
  11. export let groupId = "";
  12. export let disabled = false;
  13. export let optional = false;
  14. export let forceGroup = false;
  15. let optGroups: OptGroup[]
  16. $: {
  17. let projects = $projectStore.projects;
  18. let labels = {};
  19. if (groupId != "") {
  20. const group = $projectGroupStore.groups.find(g => g.id === groupId);
  21. if (group != null) {
  22. projects = group.projects;
  23. labels = group.categoryNames;
  24. if (forceGroup && !group.projects.find(p => p.id === value)) {
  25. value = "";
  26. }
  27. }
  28. } else if (forceGroup) {
  29. value = "";
  30. }
  31. optGroups = [
  32. {
  33. status: labels["deadlines"] || "Deadlines",
  34. projects: projects.filter(p => p.active && p.endTime)
  35. },
  36. {
  37. status: labels["active"] || "Active",
  38. projects: projects.filter(p => p.active && !p.endTime)
  39. },
  40. {
  41. status: labels["progress"] || "Progress",
  42. projects: projects.filter(p => !p.active && p.statusTag === "progress")
  43. },
  44. {
  45. status: labels["background"] || "Background",
  46. projects: projects.filter(p => !p.active && p.statusTag === "background")
  47. },
  48. {
  49. status: labels["to do"] || "To Do",
  50. projects: projects.filter(p => !p.active && p.statusTag === "to do")
  51. },
  52. {
  53. status: labels["on hold"] || "On Hold",
  54. projects: projects.filter(p => !p.active && p.statusTag === "on hold")
  55. },
  56. {
  57. status: labels["completed"] || "Completed",
  58. projects: projects.filter(p => !p.active && p.statusTag === "completed")
  59. },
  60. {
  61. status: labels["failed"] || "Failed",
  62. projects: projects.filter(p => !p.active && p.statusTag === "failed")
  63. },
  64. ]
  65. for (const group of optGroups) {
  66. group.projects.sort((a,b) => a.name.localeCompare(b.name));
  67. }
  68. }
  69. $: {
  70. if (optGroups.length > 0 && value === "" && !optional) {
  71. const nonEmpty = optGroups.find(g => g.projects.length > 0);
  72. if (nonEmpty != null) {
  73. value = nonEmpty.projects[0].id;
  74. }
  75. }
  76. }
  77. </script>
  78. <select name={name} bind:value={value} disabled={disabled || $projectStore.loading}>
  79. {#if optional}
  80. <option value={""} selected={"" === value}>{$projectStore.loading ? "Loading..." : "None"}</option>
  81. {/if}
  82. {#each optGroups as group (group.status)}
  83. {#if group.projects.length > 0}
  84. <optgroup label={group.status}>
  85. {#each group.projects as project (project.id)}
  86. <option value={project.id} selected={project.id === value}>{project.tags.length ? `${project.tags[0]}: ${project.name}` : project.name}</option>
  87. {/each}
  88. </optgroup>
  89. {/if}
  90. {/each}
  91. </select>