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.

106 lines
2.5 KiB

  1. <script lang="ts">
  2. import type { ProjectResult } from "../models/project";
  3. import type { GoalResult } from "../models/goal";
  4. export let project: ProjectResult | undefined | null;
  5. export let goal: GoalResult | undefined | null;
  6. let progressAmount: number = 0;
  7. let progressTarget: number = 0;
  8. let timeProgress: number | null = null;
  9. let boat: number | null = null;
  10. let boatNegative = false;
  11. let boatPositive = false;
  12. let boatString: string | null = null;
  13. $: {
  14. if (project != null) {
  15. progressAmount = (project.tasks||[]).map(t => (t.active || t.statusTag === "to do" || t.statusTag === "on hold")
  16. ? Math.min(t.completedAmount, t.itemAmount) * (t.item.groupWeight || 1)
  17. : t.itemAmount * (t.item.groupWeight || 1)
  18. ).reduce((n,m) => n+m, 0);
  19. progressTarget = Math.max((project.tasks||[]).map(t => t.itemAmount * (t.item.groupWeight || 1)).reduce((n,m) => n+m, 0), 1);
  20. if (project.endTime) {
  21. const start = Date.parse(project.createdTime);
  22. const end = Date.parse(project.endTime);
  23. const now = Math.min(Date.now(), end);
  24. timeProgress = (now - start) / (end - start);
  25. } else {
  26. timeProgress = null;
  27. }
  28. }
  29. if (goal != null) {
  30. const start = Date.parse(goal.startTime);
  31. const end = Date.parse(goal.endTime);
  32. const now = Math.min(Date.now(), end);
  33. progressAmount = goal.completedAmount;
  34. progressTarget = goal.amount;
  35. timeProgress = (now - start) / (end - start);
  36. }
  37. }
  38. $: {
  39. if (timeProgress != null) {
  40. const boatTarget = Math.ceil(timeProgress * progressTarget);
  41. boat = progressAmount - boatTarget;
  42. } else {
  43. boat = null;
  44. }
  45. }
  46. $: {
  47. if (boat != null) {
  48. boatNegative = boat < 0;
  49. boatPositive = boat > 0;
  50. boatString = Math.round(boat).toString(10);
  51. if (boatPositive) {
  52. boatString = '+' + boatString;
  53. }
  54. }
  55. }
  56. </script>
  57. <div class="progress">
  58. <div class="amount">{progressAmount}</div>
  59. <div class="slash">/</div>
  60. <div class="target">{progressTarget}</div>
  61. {#if boat}
  62. <div class="boat" class:positive={boatPositive} class:negative={boatNegative}>
  63. ({boatString})
  64. </div>
  65. {/if}
  66. </div>
  67. <style>
  68. div.progress {
  69. padding: 0 0.25ch;
  70. color: #555;
  71. }
  72. div.progress > div {
  73. display: inline-block;
  74. }
  75. div.slash {
  76. padding: 0 0.125ch;
  77. color: #333;
  78. }
  79. div.boat {
  80. padding-left: 0.25ch;
  81. }
  82. div.boat.negative {
  83. color: #852a24;
  84. }
  85. div.boat.positive {
  86. color: #484;
  87. }
  88. </style>