Use correct locale for number formatting
Also moved numberFormat method so separate file
This commit is contained in:
parent
68423179cc
commit
20e856ecfc
@ -28,6 +28,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, type PropType } from 'vue';
|
import { defineComponent, type PropType } from 'vue';
|
||||||
import type { InverterStatistics } from '@/types/LiveDataStatus';
|
import type { InverterStatistics } from '@/types/LiveDataStatus';
|
||||||
|
import { formatNumber } from '@/utils';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
@ -35,11 +36,7 @@ export default defineComponent({
|
|||||||
channelNumber: { type: Number, required: true },
|
channelNumber: { type: Number, required: true },
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatNumber(num: number, digits: number) {
|
formatNumber,
|
||||||
return new Intl.NumberFormat(
|
|
||||||
undefined, { minimumFractionDigits: digits, maximumFractionDigits: digits }
|
|
||||||
).format(num);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Current Limit</td>
|
<td>Current Limit</td>
|
||||||
<td>{{ formatNumber(limitData.limit) }}%</td>
|
<td>{{ formatNumber(limitData.limit, 2) }}%</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import { formatNumber } from '@/utils';
|
||||||
|
|
||||||
declare interface LimitData {
|
declare interface LimitData {
|
||||||
limit: number,
|
limit: number,
|
||||||
@ -20,14 +21,8 @@ export default defineComponent({
|
|||||||
props: {
|
props: {
|
||||||
limitData: { type: Object as () => LimitData, required: true },
|
limitData: { type: Object as () => LimitData, required: true },
|
||||||
},
|
},
|
||||||
computed: {
|
methods: {
|
||||||
formatNumber() {
|
formatNumber,
|
||||||
return (num: number) => {
|
}
|
||||||
return new Intl.NumberFormat(
|
|
||||||
undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }
|
|
||||||
).format(num)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -1,9 +1,12 @@
|
|||||||
import { timestampToString } from './time';
|
import { timestampToString } from './time';
|
||||||
|
import { formatNumber } from './number';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
timestampToString,
|
timestampToString,
|
||||||
|
formatNumber,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
timestampToString,
|
timestampToString,
|
||||||
|
formatNumber,
|
||||||
}
|
}
|
||||||
5
webapp/src/utils/number.ts
Normal file
5
webapp/src/utils/number.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export const formatNumber = (num: number, digits: number): string => {
|
||||||
|
return new Intl.NumberFormat(
|
||||||
|
undefined, { minimumFractionDigits: digits, maximumFractionDigits: digits }
|
||||||
|
).format(num);
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasePage :title="'Live Data'" :isLoading="dataLoading" :isWideScreen="true">
|
<BasePage :title="'Live Data'" :isLoading="dataLoading" :isWideScreen="true">
|
||||||
<div class="row gy-3">
|
<div class="row gy-3">
|
||||||
<div class="col-sm-3 col-md-2" :style="[inverterData.length == 1 ? {'display': 'none' } : {}]">
|
<div class="col-sm-3 col-md-2" :style="[inverterData.length == 1 ? { 'display': 'none' } : {}]">
|
||||||
<div class="nav nav-pills row-cols-sm-1" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
<div class="nav nav-pills row-cols-sm-1" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
||||||
<button v-for="inverter in inverterData" :key="inverter.serial" class="nav-link"
|
<button v-for="inverter in inverterData" :key="inverter.serial" class="nav-link"
|
||||||
:id="'v-pills-' + inverter.serial + '-tab'" data-bs-toggle="pill"
|
:id="'v-pills-' + inverter.serial + '-tab'" data-bs-toggle="pill"
|
||||||
@ -15,8 +15,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-content" id="v-pills-tabContent" :class="{'col-sm-9 col-md-10': inverterData.length > 1,
|
<div class="tab-content" id="v-pills-tabContent" :class="{
|
||||||
'col-sm-12 col-md-12': inverterData.length == 1 }">
|
'col-sm-9 col-md-10': inverterData.length > 1,
|
||||||
|
'col-sm-12 col-md-12': inverterData.length == 1
|
||||||
|
}">
|
||||||
<div v-for="inverter in inverterData" :key="inverter.serial" class="tab-pane fade show"
|
<div v-for="inverter in inverterData" :key="inverter.serial" class="tab-pane fade show"
|
||||||
:id="'v-pills-' + inverter.serial" role="tabpanel"
|
:id="'v-pills-' + inverter.serial" role="tabpanel"
|
||||||
:aria-labelledby="'v-pills-' + inverter.serial + '-tab'" tabindex="0">
|
:aria-labelledby="'v-pills-' + inverter.serial + '-tab'" tabindex="0">
|
||||||
@ -37,9 +39,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div style="padding-right: 2em;">
|
<div style="padding-right: 2em;">
|
||||||
Current Limit: <template v-if="inverter.limit_absolute > -1"> {{
|
Current Limit: <template v-if="inverter.limit_absolute > -1"> {{
|
||||||
inverter.limit_absolute.toFixed(0) }}W | </template>{{
|
formatNumber(inverter.limit_absolute, 0)
|
||||||
inverter.limit_relative.toFixed(0)
|
}}W | </template>{{ formatNumber(inverter.limit_relative, 0) }}%
|
||||||
}}%
|
|
||||||
</div>
|
</div>
|
||||||
<div style="padding-right: 2em;">
|
<div style="padding-right: 2em;">
|
||||||
Data Age: {{ inverter.data_age }} seconds
|
Data Age: {{ inverter.data_age }} seconds
|
||||||
@ -178,15 +179,16 @@
|
|||||||
Limit:</label>
|
Limit:</label>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="number" class="form-control" id="inputCurrentLimit"
|
<input type="text" class="form-control" id="inputCurrentLimit"
|
||||||
aria-describedby="currentLimitType" v-model="currentLimitRelative" disabled />
|
aria-describedby="currentLimitType" v-model="currentLimitRelative"
|
||||||
|
disabled />
|
||||||
<span class="input-group-text" id="currentLimitType">%</span>
|
<span class="input-group-text" id="currentLimitType">%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-4" v-if="currentLimitList.max_power > 0">
|
<div class="col-sm-4" v-if="currentLimitList.max_power > 0">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input type="number" class="form-control" id="inputCurrentLimitAbsolute"
|
<input type="text" class="form-control" id="inputCurrentLimitAbsolute"
|
||||||
aria-describedby="currentLimitTypeAbsolute" v-model="currentLimitAbsolute"
|
aria-describedby="currentLimitTypeAbsolute" v-model="currentLimitAbsolute"
|
||||||
disabled />
|
disabled />
|
||||||
<span class="input-group-text" id="currentLimitTypeAbsolute">W</span>
|
<span class="input-group-text" id="currentLimitTypeAbsolute">W</span>
|
||||||
@ -333,6 +335,7 @@ import type { EventlogItems } from '@/types/EventlogStatus';
|
|||||||
import type { Inverters } from '@/types/LiveDataStatus';
|
import type { Inverters } from '@/types/LiveDataStatus';
|
||||||
import type { LimitStatus } from '@/types/LimitStatus';
|
import type { LimitStatus } from '@/types/LimitStatus';
|
||||||
import type { LimitConfig } from '@/types/LimitConfig';
|
import type { LimitConfig } from '@/types/LimitConfig';
|
||||||
|
import { formatNumber } from '@/utils';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
@ -424,17 +427,18 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
currentLimitAbsolute(): number {
|
currentLimitAbsolute(): string {
|
||||||
if (this.currentLimitList.max_power > 0) {
|
if (this.currentLimitList.max_power > 0) {
|
||||||
return Number((this.currentLimitList.limit_relative * this.currentLimitList.max_power / 100).toFixed(1));
|
return formatNumber(this.currentLimitList.limit_relative * this.currentLimitList.max_power / 100, 2);
|
||||||
}
|
}
|
||||||
return 0;
|
return "0";
|
||||||
},
|
},
|
||||||
currentLimitRelative(): number {
|
currentLimitRelative(): string {
|
||||||
return Number((this.currentLimitList.limit_relative).toFixed(1));
|
return formatNumber(this.currentLimitList.limit_relative, 2);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
formatNumber,
|
||||||
getInitialData() {
|
getInitialData() {
|
||||||
this.dataLoading = true;
|
this.dataLoading = true;
|
||||||
fetch("/api/livedata/status")
|
fetch("/api/livedata/status")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user