TSK-397: Fixed time report round (#2389)

Signed-off-by: Anton Brechka <anton.brechka@xored.com>
This commit is contained in:
mrsadman99 2022-11-24 11:48:16 +03:00 committed by GitHub
parent 2238986bdb
commit 3578f2b90d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 48 additions and 39 deletions

View File

@ -22,6 +22,7 @@
import Icon from './Icon.svelte' import Icon from './Icon.svelte'
import Label from './Label.svelte' import Label from './Label.svelte'
import { resizeObserver } from '../resize' import { resizeObserver } from '../resize'
import { floorFractionDigits } from '../utils'
export let label: IntlString | undefined = undefined export let label: IntlString | undefined = undefined
export let icon: Asset | AnySvelteComponent | undefined = undefined export let icon: Asset | AnySvelteComponent | undefined = undefined
@ -30,6 +31,7 @@
export let placeholder: IntlString = plugin.string.EditBoxPlaceholder export let placeholder: IntlString = plugin.string.EditBoxPlaceholder
export let placeholderParam: any | undefined = undefined export let placeholderParam: any | undefined = undefined
export let format: 'text' | 'password' | 'number' = 'text' export let format: 'text' | 'password' | 'number' = 'text'
export let maxDigitsAfterPoint: number | undefined = undefined
export let kind: EditStyle = 'editbox' export let kind: EditStyle = 'editbox'
export let focus: boolean = false export let focus: boolean = false
export let focusable: boolean = false export let focusable: boolean = false
@ -43,6 +45,16 @@
let phTraslate: string = '' let phTraslate: string = ''
let parentWidth: number | undefined let parentWidth: number | undefined
$: {
if (
format === 'number' &&
maxDigitsAfterPoint &&
value &&
!value.toString().match(`^\\d+\\.?\\d{0,${maxDigitsAfterPoint}}$`)
) {
value = floorFractionDigits(Number(value), maxDigitsAfterPoint)
}
}
$: style = `max-width: ${ $: style = `max-width: ${
maxWidth || (parentWidth ? (icon ? `calc(${parentWidth}px - 1.25rem)` : `${parentWidth}px`) : 'max-content') maxWidth || (parentWidth ? (icon ? `calc(${parentWidth}px - 1.25rem)` : `${parentWidth}px`) : 'max-content')
};` };`

View File

@ -43,3 +43,7 @@ export function fetchMetadataLocalStorage<T> (id: Metadata<T>): T | null {
export function checkMobile (): boolean { export function checkMobile (): boolean {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|Mobile|Opera Mini/i.test(navigator.userAgent) return /Android|webOS|iPhone|iPad|iPod|BlackBerry|Mobile|Opera Mini/i.test(navigator.userAgent)
} }
export function floorFractionDigits (n: number | string, amount: number): number {
return Number(Number(n).toFixed(amount))
}

View File

@ -108,6 +108,7 @@
{kind} {kind}
placeholder={tracker.string.Estimation} placeholder={tracker.string.Estimation}
focus focus
maxDigitsAfterPoint={3}
on:keypress={_onkeypress} on:keypress={_onkeypress}
on:change={() => { on:change={() => {
if (typeof _value === 'number') { if (typeof _value === 'number') {

View File

@ -16,16 +16,15 @@
import { AttachedData } from '@hcengineering/core' import { AttachedData } from '@hcengineering/core'
import { Issue } from '@hcengineering/tracker' import { Issue } from '@hcengineering/tracker'
import { Label } from '@hcengineering/ui' import { floorFractionDigits, Label } from '@hcengineering/ui'
import tracker from '../../../plugin' import tracker from '../../../plugin'
import EstimationProgressCircle from './EstimationProgressCircle.svelte' import EstimationProgressCircle from './EstimationProgressCircle.svelte'
import { floorFractionDigits } from '../../../utils'
export let value: Issue | AttachedData<Issue> export let value: Issue | AttachedData<Issue>
$: childReportTime = floorFractionDigits( $: childReportTime = floorFractionDigits(
value.reportedTime + (value.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0), value.reportedTime + (value.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0),
2 3
) )
$: childEstimationTime = (value.childInfo ?? []).map((it) => it.estimation).reduce((a, b) => a + b, 0) $: childEstimationTime = (value.childInfo ?? []).map((it) => it.estimation).reduce((a, b) => a + b, 0)
</script> </script>
@ -41,7 +40,7 @@
{#if value.reportedTime > 0 || childReportTime > 0} {#if value.reportedTime > 0 || childReportTime > 0}
{#if childReportTime} {#if childReportTime}
{@const rchildReportTime = childReportTime} {@const rchildReportTime = childReportTime}
{@const reportDiff = floorFractionDigits(rchildReportTime - value.reportedTime, 2)} {@const reportDiff = floorFractionDigits(rchildReportTime - value.reportedTime, 3)}
{#if reportDiff !== 0 && value.reportedTime !== 0} {#if reportDiff !== 0 && value.reportedTime !== 0}
<div class="flex flex-nowrap mr-1" class:showError={reportDiff > 0}> <div class="flex flex-nowrap mr-1" class:showError={reportDiff > 0}>
<Label label={tracker.string.TimeSpendValue} params={{ value: rchildReportTime }} /> <Label label={tracker.string.TimeSpendValue} params={{ value: rchildReportTime }} />
@ -49,16 +48,16 @@
<div class="romColor"> <div class="romColor">
(<Label (<Label
label={tracker.string.TimeSpendValue} label={tracker.string.TimeSpendValue}
params={{ value: floorFractionDigits(value.reportedTime, 2) }} params={{ value: floorFractionDigits(value.reportedTime, 3) }}
/>) />)
</div> </div>
{:else if value.reportedTime === 0} {:else if value.reportedTime === 0}
<Label label={tracker.string.TimeSpendValue} params={{ value: childReportTime }} /> <Label label={tracker.string.TimeSpendValue} params={{ value: childReportTime }} />
{:else} {:else}
<Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.reportedTime, 2) }} /> <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.reportedTime, 3) }} />
{/if} {/if}
{:else} {:else}
<Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.reportedTime, 2) }} /> <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.reportedTime, 3) }} />
{/if} {/if}
<div class="p-1">/</div> <div class="p-1">/</div>
{/if} {/if}
@ -73,15 +72,15 @@
<div class="romColor"> <div class="romColor">
(<Label (<Label
label={tracker.string.TimeSpendValue} label={tracker.string.TimeSpendValue}
params={{ value: floorFractionDigits(value.estimation, 2) }} params={{ value: floorFractionDigits(value.estimation, 3) }}
/>) />)
</div> </div>
{/if} {/if}
{:else} {:else}
<Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.estimation, 2) }} /> <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.estimation, 3) }} />
{/if} {/if}
{:else} {:else}
<Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.estimation, 2) }} /> <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.estimation, 3) }} />
{/if} {/if}
</span> </span>
</div> </div>

View File

@ -16,8 +16,7 @@
<script lang="ts"> <script lang="ts">
import type { IntlString } from '@hcengineering/platform' import type { IntlString } from '@hcengineering/platform'
import { Issue } from '@hcengineering/tracker' import { Issue } from '@hcengineering/tracker'
import { ActionIcon, eventToHTMLElement, IconAdd, Label, showPopup } from '@hcengineering/ui' import { ActionIcon, eventToHTMLElement, floorFractionDigits, IconAdd, Label, showPopup } from '@hcengineering/ui'
import { floorFractionDigits } from '../../../utils'
import ReportsPopup from './ReportsPopup.svelte' import ReportsPopup from './ReportsPopup.svelte'
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte' import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
@ -39,7 +38,7 @@
} }
$: childTime = floorFractionDigits( $: childTime = floorFractionDigits(
(object.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0), (object.childInfo ?? []).map((it) => it.reportedTime).reduce((a, b) => a + b, 0),
2 3
) )
</script> </script>
@ -47,7 +46,7 @@
<div id="ReportedTimeEditor" class="link-container flex-between" on:click={showReports}> <div id="ReportedTimeEditor" class="link-container flex-between" on:click={showReports}>
{#if value !== undefined} {#if value !== undefined}
<span class="overflow-label"> <span class="overflow-label">
{floorFractionDigits(value, 2)} {floorFractionDigits(value, 3)}
{#if childTime !== 0} {#if childTime !== 0}
/ {childTime} / {childTime}
{/if} {/if}
@ -61,7 +60,7 @@
</div> </div>
{:else if value !== undefined} {:else if value !== undefined}
<span class="overflow-label"> <span class="overflow-label">
{floorFractionDigits(value, 2)} {floorFractionDigits(value, 3)}
{#if childTime !== 0} {#if childTime !== 0}
/ {childTime} / {childTime}
{/if} {/if}

View File

@ -17,11 +17,10 @@
import { WithLookup } from '@hcengineering/core' import { WithLookup } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation' import { getClient } from '@hcengineering/presentation'
import type { TimeSpendReport } from '@hcengineering/tracker' import type { TimeSpendReport } from '@hcengineering/tracker'
import { eventToHTMLElement, Label, showPopup, tooltip } from '@hcengineering/ui' import { eventToHTMLElement, floorFractionDigits, Label, showPopup, tooltip } from '@hcengineering/ui'
import view, { AttributeModel } from '@hcengineering/view' import view, { AttributeModel } from '@hcengineering/view'
import { getObjectPresenter } from '@hcengineering/view-resources' import { getObjectPresenter } from '@hcengineering/view-resources'
import tracker from '../../../plugin' import tracker from '../../../plugin'
import { floorFractionDigits } from '../../../utils'
import TimeSpendReportPopup from './TimeSpendReportPopup.svelte' import TimeSpendReportPopup from './TimeSpendReportPopup.svelte'
export let value: WithLookup<TimeSpendReport> export let value: WithLookup<TimeSpendReport>
@ -65,7 +64,7 @@
} }
: undefined} : undefined}
> >
<Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.value, 2) }} /> <Label label={tracker.string.TimeSpendValue} params={{ value: floorFractionDigits(value.value, 3) }} />
</span> </span>
{/if} {/if}

View File

@ -78,7 +78,7 @@
okLabel={value === undefined ? presentation.string.Create : presentation.string.Save} okLabel={value === undefined ? presentation.string.Create : presentation.string.Save}
> >
<div class="flex-row-center gap-2"> <div class="flex-row-center gap-2">
<EditBox focus bind:value={data.value} {placeholder} format={'number'} kind={'editbox'} /> <EditBox focus bind:value={data.value} {placeholder} format={'number'} maxDigitsAfterPoint={3} kind={'editbox'} />
<UserBox <UserBox
_class={contact.class.Employee} _class={contact.class.Employee}
label={contact.string.Employee} label={contact.string.Employee}

View File

@ -16,9 +16,8 @@
import { DocumentQuery, Ref, SortingOrder } from '@hcengineering/core' import { DocumentQuery, Ref, SortingOrder } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation' import { createQuery } from '@hcengineering/presentation'
import { Issue, Team, TimeSpendReport } from '@hcengineering/tracker' import { Issue, Team, TimeSpendReport } from '@hcengineering/tracker'
import { Label, Scroller, Spinner } from '@hcengineering/ui' import { floorFractionDigits, Label, Scroller, Spinner } from '@hcengineering/ui'
import tracker from '../../../plugin' import tracker from '../../../plugin'
import { floorFractionDigits } from '../../../utils'
import TimeSpendReportsList from './TimeSpendReportsList.svelte' import TimeSpendReportsList from './TimeSpendReportsList.svelte'
export let issue: Issue export let issue: Issue
@ -36,11 +35,8 @@
} }
}) })
$: total = floorFractionDigits( $: total = (reports ?? []).reduce((a, b) => a + floorFractionDigits(b.value, 3), 0)
(reports ?? []).reduce((a, b) => a + b.value, 0), $: reportedTime = floorFractionDigits(issue.reportedTime, 3)
2
)
$: reportedTime = floorFractionDigits(issue.reportedTime, 2)
</script> </script>
{#if reports} {#if reports}

View File

@ -17,7 +17,13 @@
import { Doc, Ref, Space, WithLookup } from '@hcengineering/core' import { Doc, Ref, Space, WithLookup } from '@hcengineering/core'
import UserBox from '@hcengineering/presentation/src/components/UserBox.svelte' import UserBox from '@hcengineering/presentation/src/components/UserBox.svelte'
import { Team, TimeSpendReport } from '@hcengineering/tracker' import { Team, TimeSpendReport } from '@hcengineering/tracker'
import { eventToHTMLElement, getEventPositionElement, ListView, showPopup } from '@hcengineering/ui' import {
eventToHTMLElement,
floorFractionDigits,
getEventPositionElement,
ListView,
showPopup
} from '@hcengineering/ui'
import DatePresenter from '@hcengineering/ui/src/components/calendar/DatePresenter.svelte' import DatePresenter from '@hcengineering/ui/src/components/calendar/DatePresenter.svelte'
import { ContextMenu, FixedColumn, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources' import { ContextMenu, FixedColumn, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
import { getIssueId } from '../../../issues' import { getIssueId } from '../../../issues'
@ -98,7 +104,7 @@
readonly readonly
showNavigate={false} showNavigate={false}
/> />
<EstimationPresenter value={report.value} /> <EstimationPresenter value={floorFractionDigits(report.value, 3)} />
<DatePresenter value={report.date} /> <DatePresenter value={report.date} />
</div> </div>
</div> </div>

View File

@ -17,12 +17,12 @@
import { IntlString } from '@hcengineering/platform' import { IntlString } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation' import { createQuery, getClient } from '@hcengineering/presentation'
import { Issue, IssueStatus, IssueTemplate, Sprint } from '@hcengineering/tracker' import { Issue, IssueStatus, IssueTemplate, Sprint } from '@hcengineering/tracker'
import type { ButtonKind, ButtonSize, ButtonShape } from '@hcengineering/ui' import { ButtonKind, ButtonSize, ButtonShape, floorFractionDigits } from '@hcengineering/ui'
import { Label, deviceOptionsStore as deviceInfo } from '@hcengineering/ui' import { Label, deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
import DatePresenter from '@hcengineering/ui/src/components/calendar/DatePresenter.svelte' import DatePresenter from '@hcengineering/ui/src/components/calendar/DatePresenter.svelte'
import { activeSprint } from '../../issues' import { activeSprint } from '../../issues'
import tracker from '../../plugin' import tracker from '../../plugin'
import { floorFractionDigits, getDayOfSprint } from '../../utils' import { getDayOfSprint } from '../../utils'
import EstimationProgressCircle from '../issues/timereport/EstimationProgressCircle.svelte' import EstimationProgressCircle from '../issues/timereport/EstimationProgressCircle.svelte'
import SprintSelector from './SprintSelector.svelte' import SprintSelector from './SprintSelector.svelte'
@ -98,7 +98,7 @@
.reduce((it, cur) => { .reduce((it, cur) => {
return it + cur return it + cur
}, 0), }, 0),
2 3
) )
$: totalReported = floorFractionDigits( $: totalReported = floorFractionDigits(
(noParents ?? [{ reportedTime: 0, childInfo: [] } as unknown as Issue]) (noParents ?? [{ reportedTime: 0, childInfo: [] } as unknown as Issue])
@ -114,7 +114,7 @@
.reduce((it, cur) => { .reduce((it, cur) => {
return it + cur return it + cur
}), }),
2 3
) )
const sprintQuery = createQuery() const sprintQuery = createQuery()

View File

@ -641,10 +641,3 @@ export async function moveIssuesToAnotherSprint (
return false return false
} }
} }
/**
* @public
*/
export const floorFractionDigits = (n: number, amount: number): number => {
return Number(n.toFixed(amount))
}