From 1aa132d66bc1f526b0bab071f1ba94416a13b739 Mon Sep 17 00:00:00 2001
From: Ruslan Bayandinov <45530296+wazsone@users.noreply.github.com>
Date: Tue, 11 Oct 2022 11:04:07 +0700
Subject: [PATCH] Fix displaying report time in different places (#2290)

* Fix report time round

Signed-off-by: Ruslan Bayandinov <wazsone@ya.ru>

* fix formatting

Signed-off-by: Ruslan Bayandinov <wazsone@ya.ru>

Signed-off-by: Ruslan Bayandinov <wazsone@ya.ru>
---
 .../src/components/ObjectSearchPopup.svelte   |  9 ---
 .../src/components/AssignedTasks.svelte       |  2 +-
 .../EstimationStatsPresenter.svelte           | 35 +++++----
 .../timereport/ReportedTimeEditor.svelte      | 10 ++-
 .../issues/timereport/TimeSpendReport.svelte  |  3 +-
 .../issues/timereport/TimeSpendReports.svelte |  9 ++-
 .../components/sprints/SprintEditor.svelte    | 76 ++++++++++---------
 plugins/tracker-resources/src/utils.ts        |  7 ++
 8 files changed, 85 insertions(+), 66 deletions(-)

diff --git a/packages/presentation/src/components/ObjectSearchPopup.svelte b/packages/presentation/src/components/ObjectSearchPopup.svelte
index 8b22ab5a20..a0df3121dc 100644
--- a/packages/presentation/src/components/ObjectSearchPopup.svelte
+++ b/packages/presentation/src/components/ObjectSearchPopup.svelte
@@ -197,15 +197,6 @@
 </form>
 
 <style lang="scss">
-  .overlay {
-    position: fixed;
-    top: 0;
-    left: 0;
-    bottom: 0;
-    right: 0;
-    z-index: 1999;
-  }
-
   .completion {
     z-index: 2000;
   }
diff --git a/plugins/task-resources/src/components/AssignedTasks.svelte b/plugins/task-resources/src/components/AssignedTasks.svelte
index e9a5f6c34c..167c2e6ef3 100644
--- a/plugins/task-resources/src/components/AssignedTasks.svelte
+++ b/plugins/task-resources/src/components/AssignedTasks.svelte
@@ -48,7 +48,7 @@
   const doneStateQuery = createQuery()
   doneStateQuery.query(task.class.DoneState, {}, (res) => (doneStates = res))
 
-  // Find all tags for object classe with matched elements
+  // Find all tags for object class with matched elements
   const query = createQuery()
 
   $: query.query(tags.class.TagReference, { tag: { $in: $selectedTagElements } }, (result) => {
diff --git a/plugins/tracker-resources/src/components/issues/timereport/EstimationStatsPresenter.svelte b/plugins/tracker-resources/src/components/issues/timereport/EstimationStatsPresenter.svelte
index aef0c7a275..e170304020 100644
--- a/plugins/tracker-resources/src/components/issues/timereport/EstimationStatsPresenter.svelte
+++ b/plugins/tracker-resources/src/components/issues/timereport/EstimationStatsPresenter.svelte
@@ -19,16 +19,15 @@
   import { Label } from '@hcengineering/ui'
   import tracker from '../../../plugin'
   import EstimationProgressCircle from './EstimationProgressCircle.svelte'
+  import { floorFractionDigits } from '../../../utils'
 
   export let value: Issue | AttachedData<Issue>
 
-  $: childReportTime =
-    value.reportedTime + (value.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0)
+  $: childReportTime = floorFractionDigits(
+    value.reportedTime + (value.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0),
+    2
+  )
   $: childEstimationTime = (value.childInfo ?? []).map((it) => it.estimation).reduce((a, b) => a + b, 0)
-
-  function hourFloor (value: number): number {
-    return Number(value.toFixed(2))
-  }
 </script>
 
 <div class="estimation-container" on:click>
@@ -38,22 +37,25 @@
   <span class="overflow-label label flex-row-center flex-nowrap text-md">
     {#if value.reportedTime > 0 || childReportTime > 0}
       {#if childReportTime}
-        {@const rchildReportTime = hourFloor(childReportTime)}
-        {@const reportDiff = rchildReportTime - hourFloor(value.reportedTime)}
+        {@const rchildReportTime = childReportTime}
+        {@const reportDiff = floorFractionDigits(rchildReportTime - value.reportedTime, 2)}
         {#if reportDiff !== 0 && value.reportedTime !== 0}
           <div class="flex flex-nowrap mr-1" class:showError={reportDiff > 0}>
             <Label label={tracker.string.TimeSpendValue} params={{ value: rchildReportTime }} />
           </div>
           <div class="romColor">
-            (<Label label={tracker.string.TimeSpendValue} params={{ value: hourFloor(value.reportedTime) }} />)
+            (<Label
+              label={tracker.string.TimeSpendValue}
+              params={{ value: floorFractionDigits(value.reportedTime, 2) }}
+            />)
           </div>
         {:else if value.reportedTime === 0}
-          <Label label={tracker.string.TimeSpendValue} params={{ value: hourFloor(childReportTime) }} />
+          <Label label={tracker.string.TimeSpendValue} params={{ value: childReportTime }} />
         {:else}
-          <Label label={tracker.string.TimeSpendValue} params={{ value: hourFloor(value.reportedTime) }} />
+          <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.reportedTime, 2) }} />
         {/if}
       {:else}
-        <Label label={tracker.string.TimeSpendValue} params={{ value: hourFloor(value.reportedTime) }} />
+        <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.reportedTime, 2) }} />
       {/if}
       <div class="p-1">/</div>
     {/if}
@@ -66,14 +68,17 @@
         </div>
         {#if value.estimation !== 0}
           <div class="romColor">
-            (<Label label={tracker.string.TimeSpendValue} params={{ value: hourFloor(value.estimation) }} />)
+            (<Label
+              label={tracker.string.TimeSpendValue}
+              params={{ value: floorFractionDigits(value.estimation, 2) }}
+            />)
           </div>
         {/if}
       {:else}
-        <Label label={tracker.string.TimeSpendValue} params={{ value: hourFloor(value.estimation) }} />
+        <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.estimation, 2) }} />
       {/if}
     {:else}
-      <Label label={tracker.string.TimeSpendValue} params={{ value: hourFloor(value.estimation) }} />
+      <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.estimation, 2) }} />
     {/if}
   </span>
 </div>
diff --git a/plugins/tracker-resources/src/components/issues/timereport/ReportedTimeEditor.svelte b/plugins/tracker-resources/src/components/issues/timereport/ReportedTimeEditor.svelte
index 2edaa8cdda..c972eb8878 100644
--- a/plugins/tracker-resources/src/components/issues/timereport/ReportedTimeEditor.svelte
+++ b/plugins/tracker-resources/src/components/issues/timereport/ReportedTimeEditor.svelte
@@ -17,6 +17,7 @@
   import type { IntlString } from '@hcengineering/platform'
   import { Issue } from '@hcengineering/tracker'
   import { ActionIcon, eventToHTMLElement, IconAdd, Label, showPopup } from '@hcengineering/ui'
+  import { floorFractionDigits } from '../../../utils'
   import ReportsPopup from './ReportsPopup.svelte'
   import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
 
@@ -36,14 +37,17 @@
   function showReports (event: MouseEvent): void {
     showPopup(ReportsPopup, { issue: object }, eventToHTMLElement(event))
   }
-  $: childTime = (object.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0)
+  $: childTime = floorFractionDigits(
+    (object.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0),
+    2
+  )
 </script>
 
 {#if kind === 'link'}
   <div class="link-container flex-between" on:click={showReports}>
     {#if value !== undefined}
       <span class="overflow-label">
-        {value}
+        {floorFractionDigits(value, 2)}
         {#if childTime !== 0}
           / {childTime}
         {/if}
@@ -57,7 +61,7 @@
   </div>
 {:else if value !== undefined}
   <span class="overflow-label">
-    {value}
+    {floorFractionDigits(value, 2)}
     {#if childTime !== 0}
       / {childTime}
     {/if}
diff --git a/plugins/tracker-resources/src/components/issues/timereport/TimeSpendReport.svelte b/plugins/tracker-resources/src/components/issues/timereport/TimeSpendReport.svelte
index 6b1cd2eb04..69ea491f4b 100644
--- a/plugins/tracker-resources/src/components/issues/timereport/TimeSpendReport.svelte
+++ b/plugins/tracker-resources/src/components/issues/timereport/TimeSpendReport.svelte
@@ -21,6 +21,7 @@
   import view, { AttributeModel } from '@hcengineering/view'
   import { getObjectPresenter } from '@hcengineering/view-resources'
   import tracker from '../../../plugin'
+  import { floorFractionDigits } from '../../../utils'
   import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
 
   export let value: WithLookup<TimeSpendReport>
@@ -63,7 +64,7 @@
         }
       : undefined}
   >
-    <Label label={tracker.string.TimeSpendValue} params={{ value: value.value }} />
+    <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.value, 2) }} />
   </span>
 {/if}
 
diff --git a/plugins/tracker-resources/src/components/issues/timereport/TimeSpendReports.svelte b/plugins/tracker-resources/src/components/issues/timereport/TimeSpendReports.svelte
index b893166542..a79484f7a5 100644
--- a/plugins/tracker-resources/src/components/issues/timereport/TimeSpendReports.svelte
+++ b/plugins/tracker-resources/src/components/issues/timereport/TimeSpendReports.svelte
@@ -18,6 +18,7 @@
   import { Issue, Team, TimeSpendReport } from '@hcengineering/tracker'
   import { Label, Scroller, Spinner } from '@hcengineering/ui'
   import tracker from '../../../plugin'
+  import { floorFractionDigits } from '../../../utils'
   import TimeSpendReportsList from './TimeSpendReportsList.svelte'
 
   export let issue: Issue
@@ -35,11 +36,15 @@
     }
   })
 
-  $: total = (reports ?? []).reduce((a, b) => a + b.value, 0)
+  $: total = floorFractionDigits(
+    (reports ?? []).reduce((a, b) => a + b.value, 0),
+    2
+  )
+  $: reportedTime = floorFractionDigits(issue.reportedTime, 2)
 </script>
 
 {#if reports}
-  <Label label={tracker.string.ReportedTime} />: {issue.reportedTime}
+  <Label label={tracker.string.ReportedTime} />: {reportedTime}
   <Label label={tracker.string.TimeSpendReports} />: {total}
   <div class="h-50">
     <Scroller>
diff --git a/plugins/tracker-resources/src/components/sprints/SprintEditor.svelte b/plugins/tracker-resources/src/components/sprints/SprintEditor.svelte
index ebd67d59c8..d9acbac747 100644
--- a/plugins/tracker-resources/src/components/sprints/SprintEditor.svelte
+++ b/plugins/tracker-resources/src/components/sprints/SprintEditor.svelte
@@ -21,7 +21,7 @@
   import DatePresenter from '@hcengineering/ui/src/components/calendar/DatePresenter.svelte'
   import { activeSprint } from '../../issues'
   import tracker from '../../plugin'
-  import { getDayOfSprint } from '../../utils'
+  import { floorFractionDigits, getDayOfSprint } from '../../utils'
   import EstimationProgressCircle from '../issues/timereport/EstimationProgressCircle.svelte'
   import SprintSelector from './SprintSelector.svelte'
 
@@ -64,47 +64,53 @@
     statuses.unsubscribe()
   }
 
-  $: totalEstimation = (noParents ?? [{ estimation: 0, childInfo: [] } as unknown as Issue])
-    .map((it) => {
-      const cat = issueStatuses.get(it.status)?.category
+  $: totalEstimation = floorFractionDigits(
+    (noParents ?? [{ estimation: 0, childInfo: [] } as unknown as Issue])
+      .map((it) => {
+        const cat = issueStatuses.get(it.status)?.category
 
-      let retEst = it.estimation
-      if (it.childInfo?.length > 0) {
-        const cEstimation = it.childInfo.map((ct) => ct.estimation).reduce((a, b) => a + b, 0)
-        const cReported = it.childInfo.map((ct) => ct.reportedTime).reduce((a, b) => a + b, 0)
-        if (cEstimation !== 0) {
-          retEst = cEstimation
+        let retEst = it.estimation
+        if (it.childInfo?.length > 0) {
+          const cEstimation = it.childInfo.map((ct) => ct.estimation).reduce((a, b) => a + b, 0)
+          const cReported = it.childInfo.map((ct) => ct.reportedTime).reduce((a, b) => a + b, 0)
+          if (cEstimation !== 0) {
+            retEst = cEstimation
+            if (cat === tracker.issueStatusCategory.Completed || cat === tracker.issueStatusCategory.Canceled) {
+              if (cReported < cEstimation) {
+                retEst = cReported
+              }
+            }
+          }
+        } else {
           if (cat === tracker.issueStatusCategory.Completed || cat === tracker.issueStatusCategory.Canceled) {
-            if (cReported < cEstimation) {
-              retEst = cReported
+            if (it.reportedTime < it.estimation) {
+              return it.reportedTime
             }
           }
         }
-      } else {
-        if (cat === tracker.issueStatusCategory.Completed || cat === tracker.issueStatusCategory.Canceled) {
-          if (it.reportedTime < it.estimation) {
-            return it.reportedTime
+        return retEst
+      })
+      .reduce((it, cur) => {
+        return it + cur
+      }),
+    2
+  )
+  $: totalReported = floorFractionDigits(
+    (noParents ?? [{ reportedTime: 0, childInfo: [] } as unknown as Issue])
+      .map((it) => {
+        if (it.childInfo?.length > 0) {
+          const cReported = it.childInfo.map((ct) => ct.reportedTime).reduce((a, b) => a + b, 0)
+          if (cReported !== 0) {
+            return cReported + it.reportedTime
           }
         }
-      }
-      return retEst
-    })
-    .reduce((it, cur) => {
-      return it + cur
-    })
-  $: totalReported = (noParents ?? [{ reportedTime: 0, childInfo: [] } as unknown as Issue])
-    .map((it) => {
-      if (it.childInfo?.length > 0) {
-        const cReported = it.childInfo.map((ct) => ct.reportedTime).reduce((a, b) => a + b, 0)
-        if (cReported !== 0) {
-          return cReported + it.reportedTime
-        }
-      }
-      return it.reportedTime
-    })
-    .reduce((it, cur) => {
-      return it + cur
-    })
+        return it.reportedTime
+      })
+      .reduce((it, cur) => {
+        return it + cur
+      }),
+    2
+  )
 
   const sprintQuery = createQuery()
   let sprint: Sprint | undefined
diff --git a/plugins/tracker-resources/src/utils.ts b/plugins/tracker-resources/src/utils.ts
index 86bd36a98f..4edbc3c963 100644
--- a/plugins/tracker-resources/src/utils.ts
+++ b/plugins/tracker-resources/src/utils.ts
@@ -619,3 +619,10 @@ export function getDayOfSprint (startDate: number, now: number): number {
   const ds = Array.from(Array(days).keys()).map((it) => stDateDate + it)
   return ds.filter((it) => !isWeekend(new Date(new Date(stTime).setDate(it)))).length
 }
+
+/**
+ * @public
+ */
+export const floorFractionDigits = (n: number, amount: number): number => {
+  return Number(n.toFixed(amount))
+}