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.

109 lines
2.7 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. progressAmount = Math.max(progressAmount - project.subtractAmount, 0);
  21. progressTarget = Math.max(progressTarget - project.subtractAmount, 0);
  22. if (project.endTime) {
  23. const start = Date.parse(project.startTime || project.createdTime);
  24. const end = Date.parse(project.endTime);
  25. const now = Math.max(Math.min(Date.now(), end), start);
  26. timeProgress = (now - start) / (end - start);
  27. } else {
  28. timeProgress = null;
  29. }
  30. }
  31. if (goal != null) {
  32. const start = Date.parse(goal.startTime);
  33. const end = Date.parse(goal.endTime);
  34. const now = Math.max(Math.min(Date.now(), end), start);
  35. progressAmount = goal.completedAmount;
  36. progressTarget = goal.amount;
  37. timeProgress = (now - start) / (end - start);
  38. }
  39. }
  40. $: {
  41. if (timeProgress != null) {
  42. const boatTarget = Math.ceil(timeProgress * progressTarget);
  43. boat = progressAmount - boatTarget;
  44. } else {
  45. boat = null;
  46. }
  47. }
  48. $: {
  49. if (boat != null) {
  50. boatNegative = boat < 0;
  51. boatPositive = boat > 0;
  52. boatString = Math.round(boat).toString(10);
  53. if (boatPositive) {
  54. boatString = '+' + boatString;
  55. }
  56. }
  57. }
  58. </script>
  59. <div class="progress">
  60. <div class="amount">{progressAmount}</div>
  61. <div class="slash">/</div>
  62. <div class="target">{progressTarget}</div>
  63. {#if boat}
  64. <div class="boat" class:positive={boatPositive} class:negative={boatNegative}>
  65. ({boatString})
  66. </div>
  67. {/if}
  68. </div>
  69. <style>
  70. div.progress {
  71. padding: 0 0.25ch;
  72. color: #555;
  73. }
  74. div.progress > div {
  75. display: inline-block;
  76. }
  77. div.slash {
  78. padding: 0 0.125ch;
  79. color: #333;
  80. }
  81. div.boat {
  82. padding-left: 0.25ch;
  83. }
  84. div.boat.negative {
  85. color: #852a24;
  86. }
  87. div.boat.positive {
  88. color: #484;
  89. }
  90. </style>