feat: add option to change date & time format in settings (#1069)
This commit is contained in:
parent
d1cfe7251d
commit
685665bd46
@ -84,6 +84,7 @@ export default class TempChart extends Mixins(BaseMixin) {
|
|||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: 'rgba(255, 255, 255, 0.24)',
|
color: 'rgba(255, 255, 255, 0.24)',
|
||||||
margin: 10,
|
margin: 10,
|
||||||
|
formatter: this.timeFormat,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
yAxis: [
|
yAxis: [
|
||||||
@ -225,8 +226,13 @@ export default class TempChart extends Mixins(BaseMixin) {
|
|||||||
return this.$store.getters['printer/tempHistory/getSelectedLegends']
|
return this.$store.getters['printer/tempHistory/getSelectedLegends']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get timeFormat() {
|
||||||
|
return this.hours12Format ? '{hh}:{mm}' : '{HH}:{mm}'
|
||||||
|
}
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initChart()
|
this.initChart()
|
||||||
|
this.chartOptions.xAxis.axisLabel.formatter = this.timeFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
@ -383,5 +389,10 @@ export default class TempChart extends Mixins(BaseMixin) {
|
|||||||
boolDisplayPwmAxisChanged() {
|
boolDisplayPwmAxisChanged() {
|
||||||
this.updateChartPwmAxis()
|
this.updateChartPwmAxis()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Watch('hours12Format')
|
||||||
|
hours12FormatChanged() {
|
||||||
|
this.chartOptions.xAxis.axisLabel.formatter = this.timeFormat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-row :class="'ma-0 ' + entryStyle">
|
<v-row :class="'ma-0 ' + entryStyle">
|
||||||
<v-col class="col-auto pr-0 text--disabled console-time">{{ event.formatTime }}</v-col>
|
<v-col class="col-auto pr-0 text--disabled console-time">{{ entryFormatTime }}</v-col>
|
||||||
<v-col
|
<v-col
|
||||||
:class="colorConsoleMessage(event) + ' ' + 'console-message'"
|
:class="colorConsoleMessage(event) + ' ' + 'console-message'"
|
||||||
@click.capture="commandClick"
|
@click.capture="commandClick"
|
||||||
@ -35,12 +35,12 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Component from 'vue-class-component'
|
import Component from 'vue-class-component'
|
||||||
import Vue from 'vue'
|
import { Mixins, Prop } from 'vue-property-decorator'
|
||||||
import { Prop } from 'vue-property-decorator'
|
|
||||||
import { ServerStateEvent } from '@/store/server/types'
|
import { ServerStateEvent } from '@/store/server/types'
|
||||||
|
import BaseMixin from '@/components/mixins/base'
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class ConsoleTableEntry extends Vue {
|
export default class ConsoleTableEntry extends Mixins(BaseMixin) {
|
||||||
@Prop({ required: true })
|
@Prop({ required: true })
|
||||||
declare readonly event: ServerStateEvent
|
declare readonly event: ServerStateEvent
|
||||||
|
|
||||||
@ -48,6 +48,10 @@ export default class ConsoleTableEntry extends Vue {
|
|||||||
return this.$store.state.gui.console.entryStyle ?? 'default'
|
return this.$store.state.gui.console.entryStyle ?? 'default'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get entryFormatTime() {
|
||||||
|
return this.formatTime(this.event.date.getTime(), true)
|
||||||
|
}
|
||||||
|
|
||||||
colorConsoleMessage(item: ServerStateEvent): string {
|
colorConsoleMessage(item: ServerStateEvent): string {
|
||||||
if (item.message.startsWith('!! ')) return 'error--text'
|
if (item.message.startsWith('!! ')) return 'error--text'
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Component from 'vue-class-component'
|
import Component from 'vue-class-component'
|
||||||
|
import { DateTimeFormatOptions } from 'vue-i18n'
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class BaseMixin extends Vue {
|
export default class BaseMixin extends Vue {
|
||||||
@ -87,4 +88,96 @@ export default class BaseMixin extends Vue {
|
|||||||
|
|
||||||
return roots.findIndex((root: string) => root === 'gcodes') >= 0
|
return roots.findIndex((root: string) => root === 'gcodes') >= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get formatDateOptions(): DateTimeFormatOptions {
|
||||||
|
const format = this.$store.state.gui.general.dateFormat
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case '2-digits':
|
||||||
|
return { day: '2-digit', month: '2-digit', year: 'numeric' }
|
||||||
|
|
||||||
|
case 'short':
|
||||||
|
return { day: '2-digit', month: 'short', year: 'numeric' }
|
||||||
|
|
||||||
|
default:
|
||||||
|
return { dateStyle: 'medium' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get formatTimeOptions(): DateTimeFormatOptions {
|
||||||
|
const format = this.$store.state.gui.general.timeFormat
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case '24hours':
|
||||||
|
return { hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }
|
||||||
|
|
||||||
|
case '12hours':
|
||||||
|
return { hour: '2-digit', minute: '2-digit', hourCycle: 'h12' }
|
||||||
|
|
||||||
|
default:
|
||||||
|
return { timeStyle: 'short' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get formatTimeWithSecondsOptions(): DateTimeFormatOptions {
|
||||||
|
const format = this.$store.state.gui.general.timeFormat
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case '24hours':
|
||||||
|
return { hour: '2-digit', minute: '2-digit', second: '2-digit', hourCycle: 'h23' }
|
||||||
|
|
||||||
|
case '12hours':
|
||||||
|
return { hour: '2-digit', minute: '2-digit', second: '2-digit', hourCycle: 'h12' }
|
||||||
|
|
||||||
|
default:
|
||||||
|
return { timeStyle: 'short' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get browserLocale() {
|
||||||
|
return navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.language
|
||||||
|
}
|
||||||
|
|
||||||
|
get hours12Format() {
|
||||||
|
const setting = this.$store.state.gui.general.timeFormat
|
||||||
|
if (setting === '12hours') return true
|
||||||
|
if (setting === null && this.browserLocale === 'en_us') return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
formatDate(value: number | Date): string {
|
||||||
|
let tmp = null
|
||||||
|
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
tmp = (typeof value.getMonth === 'function' ? value : new Date(value)) as Date
|
||||||
|
} catch (_) {
|
||||||
|
return 'UNKNOWN'
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmp.toLocaleDateString(this.browserLocale, this.formatDateOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
formatTime(value: number | Date, boolSeconds = false): string {
|
||||||
|
let tmp = null
|
||||||
|
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
tmp = (typeof value.getMonth === 'function' ? value : new Date(value)) as Date
|
||||||
|
} catch (_) {
|
||||||
|
return 'UNKNOWN'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boolSeconds) return tmp.toLocaleTimeString(this.browserLocale, this.formatTimeWithSecondsOptions)
|
||||||
|
|
||||||
|
return tmp.toLocaleTimeString(this.browserLocale, this.formatTimeOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
formatDateTime(value: number, boolSeconds = false): string {
|
||||||
|
const date = this.formatDate(value)
|
||||||
|
const time = this.formatTime(value, boolSeconds)
|
||||||
|
|
||||||
|
return `${date} ${time}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,7 +494,7 @@
|
|||||||
import { Component, Mixins, Watch } from 'vue-property-decorator'
|
import { Component, Mixins, Watch } from 'vue-property-decorator'
|
||||||
import BaseMixin from '@/components/mixins/base'
|
import BaseMixin from '@/components/mixins/base'
|
||||||
import { validGcodeExtensions } from '@/store/variables'
|
import { validGcodeExtensions } from '@/store/variables'
|
||||||
import { formatDate, formatFilesize, formatPrintTime, sortFiles } from '@/plugins/helpers'
|
import { formatFilesize, formatPrintTime, sortFiles } from '@/plugins/helpers'
|
||||||
import { FileStateFile, FileStateGcodefile } from '@/store/files/types'
|
import { FileStateFile, FileStateGcodefile } from '@/store/files/types'
|
||||||
import Panel from '@/components/ui/Panel.vue'
|
import Panel from '@/components/ui/Panel.vue'
|
||||||
import SettingsRow from '@/components/settings/SettingsRow.vue'
|
import SettingsRow from '@/components/settings/SettingsRow.vue'
|
||||||
@ -586,7 +586,6 @@ export default class GcodefilesPanel extends Mixins(BaseMixin, ControlMixin) {
|
|||||||
mdiDragVertical = mdiDragVertical
|
mdiDragVertical = mdiDragVertical
|
||||||
|
|
||||||
validGcodeExtensions = validGcodeExtensions
|
validGcodeExtensions = validGcodeExtensions
|
||||||
formatDate = formatDate
|
|
||||||
formatFilesize = formatFilesize
|
formatFilesize = formatFilesize
|
||||||
formatPrintTime = formatPrintTime
|
formatPrintTime = formatPrintTime
|
||||||
sortFiles = sortFiles
|
sortFiles = sortFiles
|
||||||
@ -1269,7 +1268,7 @@ export default class GcodefilesPanel extends Mixins(BaseMixin, ControlMixin) {
|
|||||||
return formatFilesize(value)
|
return formatFilesize(value)
|
||||||
|
|
||||||
case 'date':
|
case 'date':
|
||||||
return this.formatDate(value)
|
return this.formatDateTime(value)
|
||||||
|
|
||||||
case 'time':
|
case 'time':
|
||||||
return this.formatPrintTime(value)
|
return this.formatPrintTime(value)
|
||||||
|
@ -272,7 +272,9 @@
|
|||||||
<v-divider class="my-3"></v-divider>
|
<v-divider class="my-3"></v-divider>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>{{ $t('History.LastModified') }}</v-col>
|
<v-col>{{ $t('History.LastModified') }}</v-col>
|
||||||
<v-col class="text-right">{{ formatDate(detailsDialog.item.metadata.modified) }}</v-col>
|
<v-col class="text-right">
|
||||||
|
{{ formatDateTime(detailsDialog.item.metadata.modified) }}
|
||||||
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</template>
|
</template>
|
||||||
<v-divider class="my-3"></v-divider>
|
<v-divider class="my-3"></v-divider>
|
||||||
@ -289,13 +291,13 @@
|
|||||||
<v-divider class="my-3"></v-divider>
|
<v-divider class="my-3"></v-divider>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>{{ $t('History.StartTime') }}</v-col>
|
<v-col>{{ $t('History.StartTime') }}</v-col>
|
||||||
<v-col class="text-right">{{ formatDate(detailsDialog.item.start_time) }}</v-col>
|
<v-col class="text-right">{{ formatDateTime(detailsDialog.item.start_time) }}</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<template v-if="'end_time' in detailsDialog.item && detailsDialog.item.end_time > 0">
|
<template v-if="'end_time' in detailsDialog.item && detailsDialog.item.end_time > 0">
|
||||||
<v-divider class="my-3"></v-divider>
|
<v-divider class="my-3"></v-divider>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col>{{ $t('History.EndTime') }}</v-col>
|
<v-col>{{ $t('History.EndTime') }}</v-col>
|
||||||
<v-col class="text-right">{{ formatDate(detailsDialog.item.end_time) }}</v-col>
|
<v-col class="text-right">{{ formatDateTime(detailsDialog.item.end_time) }}</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</template>
|
</template>
|
||||||
<template
|
<template
|
||||||
@ -761,12 +763,6 @@ export default class HistoryListPanel extends Mixins(BaseMixin) {
|
|||||||
this.$socket.emit('server.history.list', { start: 0, limit: 50 }, { action: 'server/history/getHistory' })
|
this.$socket.emit('server.history.list', { start: 0, limit: 50 }, { action: 'server/history/getHistory' })
|
||||||
}
|
}
|
||||||
|
|
||||||
formatDate(date: number) {
|
|
||||||
const tmp2 = new Date(date * 1000)
|
|
||||||
|
|
||||||
return tmp2.toLocaleString().replace(',', '')
|
|
||||||
}
|
|
||||||
|
|
||||||
formatPrintTime(totalSeconds: number) {
|
formatPrintTime(totalSeconds: number) {
|
||||||
if (totalSeconds) {
|
if (totalSeconds) {
|
||||||
let output = ''
|
let output = ''
|
||||||
@ -1013,7 +1009,7 @@ export default class HistoryListPanel extends Mixins(BaseMixin) {
|
|||||||
if (!format) {
|
if (!format) {
|
||||||
switch (col.outputType) {
|
switch (col.outputType) {
|
||||||
case 'date':
|
case 'date':
|
||||||
return this.formatDate(value)
|
return this.formatDateTime(value * 1000)
|
||||||
|
|
||||||
case 'time':
|
case 'time':
|
||||||
return value?.toFixed() ?? ''
|
return value?.toFixed() ?? ''
|
||||||
@ -1038,7 +1034,7 @@ export default class HistoryListPanel extends Mixins(BaseMixin) {
|
|||||||
return formatFilesize(value)
|
return formatFilesize(value)
|
||||||
|
|
||||||
case 'date':
|
case 'date':
|
||||||
return this.formatDate(value)
|
return this.formatDateTime(value * 1000)
|
||||||
|
|
||||||
case 'time':
|
case 'time':
|
||||||
return this.formatPrintTime(value)
|
return this.formatPrintTime(value)
|
||||||
|
@ -162,7 +162,7 @@
|
|||||||
<td class="text-no-wrap text-right">
|
<td class="text-no-wrap text-right">
|
||||||
{{ item.isDirectory ? '--' : formatFilesize(item.size) }}
|
{{ item.isDirectory ? '--' : formatFilesize(item.size) }}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">{{ formatDate(item.modified) }}</td>
|
<td class="text-right">{{ formatDateTime(item.modified) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
</v-data-table>
|
</v-data-table>
|
||||||
@ -462,7 +462,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Mixins } from 'vue-property-decorator'
|
import { Component, Mixins } from 'vue-property-decorator'
|
||||||
import BaseMixin from '@/components/mixins/base'
|
import BaseMixin from '@/components/mixins/base'
|
||||||
import { formatDate, formatFilesize, sortFiles } from '@/plugins/helpers'
|
import { formatFilesize, sortFiles } from '@/plugins/helpers'
|
||||||
import { FileStateFile, FileStateGcodefile } from '@/store/files/types'
|
import { FileStateFile, FileStateGcodefile } from '@/store/files/types'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import Panel from '@/components/ui/Panel.vue'
|
import Panel from '@/components/ui/Panel.vue'
|
||||||
@ -553,7 +553,6 @@ export default class ConfigFilesPanel extends Mixins(BaseMixin) {
|
|||||||
|
|
||||||
sortFiles = sortFiles
|
sortFiles = sortFiles
|
||||||
formatFilesize = formatFilesize
|
formatFilesize = formatFilesize
|
||||||
formatDate = formatDate
|
|
||||||
|
|
||||||
declare $refs: {
|
declare $refs: {
|
||||||
fileUpload: HTMLInputElement
|
fileUpload: HTMLInputElement
|
||||||
|
@ -81,16 +81,16 @@
|
|||||||
<strong>{{ $t('Panels.StatusPanel.Estimate') }}</strong>
|
<strong>{{ $t('Panels.StatusPanel.Estimate') }}</strong>
|
||||||
<br />
|
<br />
|
||||||
<span class="text-no-wrap">
|
<span class="text-no-wrap">
|
||||||
{{ estimated_time_avg ? formatTime(estimated_time_avg) : '--' }}
|
{{ estimated_time_avg ? formatDuration(estimated_time_avg) : '--' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
{{ $t('Panels.StatusPanel.File') }}:
|
{{ $t('Panels.StatusPanel.File') }}:
|
||||||
{{ estimated_time_file ? formatTime(estimated_time_file) : '--' }}
|
{{ estimated_time_file ? formatDuration(estimated_time_file) : '--' }}
|
||||||
<br />
|
<br />
|
||||||
{{ $t('Panels.StatusPanel.Filament') }}:
|
{{ $t('Panels.StatusPanel.Filament') }}:
|
||||||
{{ estimated_time_filament ? formatTime(estimated_time_filament) : '--' }}
|
{{ estimated_time_filament ? formatDuration(estimated_time_filament) : '--' }}
|
||||||
</div>
|
</div>
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</v-col>
|
</v-col>
|
||||||
@ -98,7 +98,7 @@
|
|||||||
<strong>{{ $t('Panels.StatusPanel.Slicer') }}</strong>
|
<strong>{{ $t('Panels.StatusPanel.Slicer') }}</strong>
|
||||||
<br />
|
<br />
|
||||||
<span class="text-no-wrap">
|
<span class="text-no-wrap">
|
||||||
{{ estimated_time_slicer ? formatTime(estimated_time_slicer) : '--' }}
|
{{ estimated_time_slicer ? formatDuration(estimated_time_slicer) : '--' }}
|
||||||
</span>
|
</span>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col class="col-3 pa-0">
|
<v-col class="col-3 pa-0">
|
||||||
@ -108,23 +108,23 @@
|
|||||||
<strong>{{ $t('Panels.StatusPanel.Total') }}</strong>
|
<strong>{{ $t('Panels.StatusPanel.Total') }}</strong>
|
||||||
<br />
|
<br />
|
||||||
<span class="text-no-wrap">
|
<span class="text-no-wrap">
|
||||||
{{ print_time_total ? formatTime(print_time_total) : '--' }}
|
{{ print_time_total ? formatDuration(print_time_total) : '--' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
{{ $t('Panels.StatusPanel.Print') }}:
|
{{ $t('Panels.StatusPanel.Print') }}:
|
||||||
{{ print_time ? formatTime(print_time) : '--' }}
|
{{ print_time ? formatDuration(print_time) : '--' }}
|
||||||
<br />
|
<br />
|
||||||
{{ $t('Panels.StatusPanel.Difference') }}:
|
{{ $t('Panels.StatusPanel.Difference') }}:
|
||||||
{{ print_time && print_time_total ? formatTime(print_time_total - print_time) : '--' }}
|
{{ print_time && print_time_total ? formatDuration(print_time_total - print_time) : '--' }}
|
||||||
</div>
|
</div>
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col class="col-3 pa-0">
|
<v-col class="col-3 pa-0">
|
||||||
<strong>{{ $t('Panels.StatusPanel.ETA') }}</strong>
|
<strong>{{ $t('Panels.StatusPanel.ETA') }}</strong>
|
||||||
<br />
|
<br />
|
||||||
<span class="text-no-wrap">{{ outputEta }}</span>
|
<span class="text-no-wrap">{{ eta }}</span>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
@ -213,11 +213,7 @@ export default class StatusPanelPrintstatusPrinting extends Mixins(BaseMixin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get eta() {
|
get eta() {
|
||||||
return this.$store.getters['printer/getEstimatedTimeETA']
|
return this.$store.getters['printer/getEstimatedTimeETAFormat']
|
||||||
}
|
|
||||||
|
|
||||||
get outputEta() {
|
|
||||||
return this.eta ? this.formatDateTime(this.eta) : '--'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get filament_diameter() {
|
get filament_diameter() {
|
||||||
@ -242,7 +238,7 @@ export default class StatusPanelPrintstatusPrinting extends Mixins(BaseMixin) {
|
|||||||
: this.filament_used.toFixed(2) + ' mm'
|
: this.filament_used.toFixed(2) + ' mm'
|
||||||
}
|
}
|
||||||
|
|
||||||
formatTime(seconds: number) {
|
formatDuration(seconds: number) {
|
||||||
let h = Math.floor(seconds / 3600)
|
let h = Math.floor(seconds / 3600)
|
||||||
seconds %= 3600
|
seconds %= 3600
|
||||||
let m = ('0' + Math.floor(seconds / 60)).slice(-2)
|
let m = ('0' + Math.floor(seconds / 60)).slice(-2)
|
||||||
@ -250,14 +246,5 @@ export default class StatusPanelPrintstatusPrinting extends Mixins(BaseMixin) {
|
|||||||
|
|
||||||
return h + ':' + m + ':' + s
|
return h + ':' + m + ':' + s
|
||||||
}
|
}
|
||||||
|
|
||||||
formatDateTime(msec: number) {
|
|
||||||
const date = new Date(msec)
|
|
||||||
const h = date.getHours() >= 10 ? date.getHours() : '0' + date.getHours()
|
|
||||||
const m = date.getMinutes() >= 10 ? date.getMinutes() : '0' + date.getMinutes()
|
|
||||||
|
|
||||||
const diff = msec - new Date().getTime()
|
|
||||||
return h + ':' + m + (diff > 60 * 60 * 24 * 1000 ? '+' + Math.round(diff / (60 * 60 * 24 * 1000)) : '')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -181,7 +181,7 @@
|
|||||||
{{ item.isDirectory ? '--' : formatFilesize(item.size) }}
|
{{ item.isDirectory ? '--' : formatFilesize(item.size) }}
|
||||||
</td>
|
</td>
|
||||||
<td v-if="headers.find((header) => header.value === 'modified').visible" class="text-right">
|
<td v-if="headers.find((header) => header.value === 'modified').visible" class="text-right">
|
||||||
{{ formatDate(item.modified) }}
|
{{ formatDateTime(item.modified) }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
@ -396,7 +396,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Mixins } from 'vue-property-decorator'
|
import { Component, Mixins } from 'vue-property-decorator'
|
||||||
import BaseMixin from '@/components/mixins/base'
|
import BaseMixin from '@/components/mixins/base'
|
||||||
import { formatFilesize, formatDate, sortFiles } from '@/plugins/helpers'
|
import { formatFilesize, sortFiles } from '@/plugins/helpers'
|
||||||
import { FileStateFile, FileStateGcodefile } from '@/store/files/types'
|
import { FileStateFile, FileStateGcodefile } from '@/store/files/types'
|
||||||
import Panel from '@/components/ui/Panel.vue'
|
import Panel from '@/components/ui/Panel.vue'
|
||||||
import {
|
import {
|
||||||
@ -425,7 +425,6 @@ interface dialogRenameObject {
|
|||||||
components: { Panel },
|
components: { Panel },
|
||||||
})
|
})
|
||||||
export default class TimelapseFilesPanel extends Mixins(BaseMixin) {
|
export default class TimelapseFilesPanel extends Mixins(BaseMixin) {
|
||||||
formatDate = formatDate
|
|
||||||
formatFilesize = formatFilesize
|
formatFilesize = formatFilesize
|
||||||
sortFiles = sortFiles
|
sortFiles = sortFiles
|
||||||
|
|
||||||
|
@ -16,6 +16,26 @@
|
|||||||
attach></v-select>
|
attach></v-select>
|
||||||
</settings-row>
|
</settings-row>
|
||||||
<v-divider class="my-2"></v-divider>
|
<v-divider class="my-2"></v-divider>
|
||||||
|
<settings-row :title="$t('Settings.GeneralTab.DateFormat').toString()">
|
||||||
|
<v-select
|
||||||
|
v-model="dateFormat"
|
||||||
|
:items="dateFormatItems"
|
||||||
|
hide-details
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
attach></v-select>
|
||||||
|
</settings-row>
|
||||||
|
<v-divider class="my-2"></v-divider>
|
||||||
|
<settings-row :title="$t('Settings.GeneralTab.TimeFormat').toString()">
|
||||||
|
<v-select
|
||||||
|
v-model="timeFormat"
|
||||||
|
:items="timeFormatItems"
|
||||||
|
hide-details
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
attach></v-select>
|
||||||
|
</settings-row>
|
||||||
|
<v-divider class="my-2"></v-divider>
|
||||||
<settings-row
|
<settings-row
|
||||||
:title="$t('Settings.GeneralTab.CalcPrintProgress').toString()"
|
:title="$t('Settings.GeneralTab.CalcPrintProgress').toString()"
|
||||||
:sub-title="$t('Settings.GeneralTab.CalcPrintProgressDescription').toString()">
|
:sub-title="$t('Settings.GeneralTab.CalcPrintProgressDescription').toString()">
|
||||||
@ -364,6 +384,62 @@ export default class SettingsGeneralTab extends Mixins(BaseMixin) {
|
|||||||
return languages
|
return languages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get dateFormat() {
|
||||||
|
return this.$store.state.gui.general.dateFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
set dateFormat(newVal) {
|
||||||
|
this.$store.dispatch('gui/saveSetting', { name: 'general.dateFormat', value: newVal })
|
||||||
|
}
|
||||||
|
|
||||||
|
get dateFormatItems() {
|
||||||
|
const date = new Date()
|
||||||
|
const userLocale =
|
||||||
|
navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.language
|
||||||
|
|
||||||
|
return [
|
||||||
|
{ value: null, text: `Browser (${date.toLocaleDateString(userLocale, { dateStyle: 'medium' })})` },
|
||||||
|
{
|
||||||
|
value: '2-digits',
|
||||||
|
text: date.toLocaleDateString(userLocale, { day: '2-digit', month: '2-digit', year: 'numeric' }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'short',
|
||||||
|
text: date.toLocaleDateString(userLocale, { day: '2-digit', month: 'short', year: 'numeric' }),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
get timeFormat() {
|
||||||
|
return this.$store.state.gui.general.timeFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
set timeFormat(newVal) {
|
||||||
|
this.$store.dispatch('gui/saveSetting', { name: 'general.timeFormat', value: newVal })
|
||||||
|
}
|
||||||
|
|
||||||
|
get timeFormatItems() {
|
||||||
|
const date = new Date()
|
||||||
|
const userLocale =
|
||||||
|
navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.language
|
||||||
|
|
||||||
|
return [
|
||||||
|
{ value: null, text: `Browser (${date.toLocaleTimeString(userLocale, { timeStyle: 'short' })})` },
|
||||||
|
{
|
||||||
|
value: '24hours',
|
||||||
|
text: this.$t('Settings.GeneralTab.24hours', {
|
||||||
|
time: date.toLocaleTimeString(userLocale, { hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }),
|
||||||
|
}).toString(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '12hours',
|
||||||
|
text: this.$t('Settings.GeneralTab.12hours', {
|
||||||
|
time: date.toLocaleTimeString(userLocale, { hour: '2-digit', minute: '2-digit', hourCycle: 'h12' }),
|
||||||
|
}).toString(),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
get calcPrintProgressItems() {
|
get calcPrintProgressItems() {
|
||||||
return [
|
return [
|
||||||
{ value: 'file-relative', text: this.$t('Settings.GeneralTab.CalcPrintProgressItems.FileRelative') },
|
{ value: 'file-relative', text: this.$t('Settings.GeneralTab.CalcPrintProgressItems.FileRelative') },
|
||||||
|
@ -760,6 +760,8 @@
|
|||||||
"ShowAxes": "Show Axes"
|
"ShowAxes": "Show Axes"
|
||||||
},
|
},
|
||||||
"GeneralTab": {
|
"GeneralTab": {
|
||||||
|
"12hours": "12-hours ({time})",
|
||||||
|
"24hours": "24-hours ({time})",
|
||||||
"Backup": "Backup",
|
"Backup": "Backup",
|
||||||
"BackupDialog": "Please select all the sections you want to create a backup:",
|
"BackupDialog": "Please select all the sections you want to create a backup:",
|
||||||
"CalcEstimateTime": "Estimate time calculation",
|
"CalcEstimateTime": "Estimate time calculation",
|
||||||
@ -775,6 +777,7 @@
|
|||||||
"Slicer": "Slicer (M73)"
|
"Slicer": "Slicer (M73)"
|
||||||
},
|
},
|
||||||
"CannotReadJson": "Cannot read/parse backup file.",
|
"CannotReadJson": "Cannot read/parse backup file.",
|
||||||
|
"DateFormat": "Date Format",
|
||||||
"DbConsoleHistory": "Console History",
|
"DbConsoleHistory": "Console History",
|
||||||
"DbHistoryJobs": "History Jobs",
|
"DbHistoryJobs": "History Jobs",
|
||||||
"DbHistoryTotals": "History Totals",
|
"DbHistoryTotals": "History Totals",
|
||||||
@ -794,7 +797,8 @@
|
|||||||
"PrinterName": "Printer Name",
|
"PrinterName": "Printer Name",
|
||||||
"Reset": "reset",
|
"Reset": "reset",
|
||||||
"Restore": "Restore",
|
"Restore": "Restore",
|
||||||
"RestoreDialog": "Please select all the sections you want to restore:"
|
"RestoreDialog": "Please select all the sections you want to restore:",
|
||||||
|
"TimeFormat": "Time Format"
|
||||||
},
|
},
|
||||||
"InterfaceSettings": "Interface Settings",
|
"InterfaceSettings": "Interface Settings",
|
||||||
"MacrosTab": {
|
"MacrosTab": {
|
||||||
|
@ -134,12 +134,6 @@ export const formatFilesize = (fileSizeInBytes: number): string => {
|
|||||||
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i]
|
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const formatDate = (date: number): string => {
|
|
||||||
const tmp2 = new Date(date)
|
|
||||||
|
|
||||||
return tmp2.toLocaleString().replace(',', '')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const formatFrequency = (frequency: number): string => {
|
export const formatFrequency = (frequency: number): string => {
|
||||||
let i = -1
|
let i = -1
|
||||||
const units = [' kHz', ' MHz', ' GHz']
|
const units = [' kHz', ' MHz', ' GHz']
|
||||||
|
@ -20,24 +20,15 @@ export const getters: GetterTree<RootState, any> = {
|
|||||||
if (state.server?.klippy_state !== 'ready') return i18n.t('App.Titles.Error')
|
if (state.server?.klippy_state !== 'ready') return i18n.t('App.Titles.Error')
|
||||||
else if (printer_state === 'paused') return i18n.t('App.Titles.Pause')
|
else if (printer_state === 'paused') return i18n.t('App.Titles.Pause')
|
||||||
else if (printer_state === 'printing') {
|
else if (printer_state === 'printing') {
|
||||||
const eta = getters['printer/getEstimatedTimeETA']
|
const eta = getters['printer/getEstimatedTimeETAFormat']
|
||||||
|
|
||||||
if (eta) {
|
|
||||||
const date = new Date(eta)
|
|
||||||
const h = date.getHours() >= 10 ? date.getHours() : '0' + date.getHours()
|
|
||||||
const m = date.getMinutes() >= 10 ? date.getMinutes() : '0' + date.getMinutes()
|
|
||||||
const diff = eta - new Date().getTime()
|
|
||||||
|
|
||||||
|
if (eta !== '--')
|
||||||
return i18n.t('App.Titles.PrintingETA', {
|
return i18n.t('App.Titles.PrintingETA', {
|
||||||
percent: (getters['printer/getPrintPercent'] * 100).toFixed(0),
|
percent: (getters['printer/getPrintPercent'] * 100).toFixed(0),
|
||||||
filename: state.printer.print_stats?.filename,
|
filename: state.printer.print_stats?.filename,
|
||||||
eta:
|
eta,
|
||||||
h +
|
|
||||||
':' +
|
|
||||||
m +
|
|
||||||
(diff > 60 * 60 * 24 * 1000 ? '+' + (diff / (60 * 60 * 24 * 1000)).toFixed() : ''),
|
|
||||||
})
|
})
|
||||||
} else
|
else
|
||||||
return i18n.t('App.Titles.Printing', {
|
return i18n.t('App.Titles.Printing', {
|
||||||
percent: (getters['printer/getPrintPercent'] * 100).toFixed(0),
|
percent: (getters['printer/getPrintPercent'] * 100).toFixed(0),
|
||||||
filename: state.printer.print_stats?.filename,
|
filename: state.printer.print_stats?.filename,
|
||||||
|
@ -69,4 +69,17 @@ export const getters: GetterTree<GuiState, any> = {
|
|||||||
|
|
||||||
return 'm84'
|
return 'm84'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getHours12Format: (state) => {
|
||||||
|
const setting = state.general.timeFormat
|
||||||
|
if (setting === '12hours') return true
|
||||||
|
if (setting === null) {
|
||||||
|
const browserLocale =
|
||||||
|
navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.language
|
||||||
|
|
||||||
|
if (browserLocale === 'en_us') return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ export const getDefaultState = (): GuiState => {
|
|||||||
general: {
|
general: {
|
||||||
printername: '',
|
printername: '',
|
||||||
language: 'en',
|
language: 'en',
|
||||||
|
dateFormat: null,
|
||||||
|
timeFormat: null,
|
||||||
calcPrintProgress: 'file-relative',
|
calcPrintProgress: 'file-relative',
|
||||||
calcEstimateTime: ['file', 'filament'],
|
calcEstimateTime: ['file', 'filament'],
|
||||||
calcEtaTime: ['file', 'filament', 'slicer'],
|
calcEtaTime: ['file', 'filament', 'slicer'],
|
||||||
|
@ -10,6 +10,8 @@ export interface GuiState {
|
|||||||
general: {
|
general: {
|
||||||
printername: string
|
printername: string
|
||||||
language: string
|
language: string
|
||||||
|
dateFormat: string | null
|
||||||
|
timeFormat: string | null
|
||||||
calcPrintProgress: 'file-relative' | 'file-absolute' | 'slicer' | 'filament'
|
calcPrintProgress: 'file-relative' | 'file-absolute' | 'slicer' | 'filament'
|
||||||
calcEstimateTime: string[] // file, filament are possible values
|
calcEstimateTime: string[] // file, filament are possible values
|
||||||
calcEtaTime: string[] // file, filament, slicer are possible values
|
calcEtaTime: string[] // file, filament, slicer are possible values
|
||||||
|
@ -958,6 +958,30 @@ export const getters: GetterTree<PrinterState, RootState> = {
|
|||||||
return 0
|
return 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getEstimatedTimeETAFormat: (state, getters, rootState, rootGetters) => {
|
||||||
|
const hours12Format = rootGetters['gui/getHours12Format'] ?? false
|
||||||
|
const eta = getters['getEstimatedTimeETA']
|
||||||
|
if (eta === 0) return '--'
|
||||||
|
|
||||||
|
const date = new Date(eta)
|
||||||
|
let am = true
|
||||||
|
let h: string | number = date.getHours()
|
||||||
|
if (hours12Format && h > 12) {
|
||||||
|
am = false
|
||||||
|
h -= 12
|
||||||
|
}
|
||||||
|
if (h < 10) h = '0' + h
|
||||||
|
|
||||||
|
const m = date.getMinutes() >= 10 ? date.getMinutes() : '0' + date.getMinutes()
|
||||||
|
|
||||||
|
const diff = eta - new Date().getTime()
|
||||||
|
let output = h + ':' + m
|
||||||
|
if (hours12Format) output += ` ${am ? 'AM' : 'PM'}`
|
||||||
|
if (diff > 60 * 60 * 24 * 1000) output += `+${Math.trunc(diff / (60 * 60 * 24 * 1000))}`
|
||||||
|
|
||||||
|
return output
|
||||||
|
},
|
||||||
|
|
||||||
getToolchangeMacros: (state, getters) => {
|
getToolchangeMacros: (state, getters) => {
|
||||||
const macros = getters['getMacros']
|
const macros = getters['getMacros']
|
||||||
const tools: PrinterStateToolchangeMacro[] = []
|
const tools: PrinterStateToolchangeMacro[] = []
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { GetterTree } from 'vuex'
|
import { GetterTree } from 'vuex'
|
||||||
import { ServerState, ServerStateNetworkInterface } from '@/store/server/types'
|
import { ServerState, ServerStateNetworkInterface } from '@/store/server/types'
|
||||||
import { formatConsoleMessage, formatFilesize, formatTime } from '@/plugins/helpers'
|
import { formatConsoleMessage, formatFilesize } from '@/plugins/helpers'
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
export const getters: GetterTree<ServerState, any> = {
|
export const getters: GetterTree<ServerState, any> = {
|
||||||
@ -22,7 +22,6 @@ export const getters: GetterTree<ServerState, any> = {
|
|||||||
|
|
||||||
events.unshift({
|
events.unshift({
|
||||||
date: date,
|
date: date,
|
||||||
formatTime: formatTime(date),
|
|
||||||
message: message,
|
message: message,
|
||||||
formatMessage: formatConsoleMessage(message),
|
formatMessage: formatConsoleMessage(message),
|
||||||
type: 'response',
|
type: 'response',
|
||||||
|
@ -2,7 +2,7 @@ import Vue from 'vue'
|
|||||||
import { getDefaultState } from './index'
|
import { getDefaultState } from './index'
|
||||||
import { MutationTree } from 'vuex'
|
import { MutationTree } from 'vuex'
|
||||||
import { ServerState } from '@/store/server/types'
|
import { ServerState } from '@/store/server/types'
|
||||||
import { formatConsoleMessage, formatTime } from '@/plugins/helpers'
|
import { formatConsoleMessage } from '@/plugins/helpers'
|
||||||
import { maxEventHistory } from '@/store/variables'
|
import { maxEventHistory } from '@/store/variables'
|
||||||
|
|
||||||
export const mutations: MutationTree<ServerState> = {
|
export const mutations: MutationTree<ServerState> = {
|
||||||
@ -105,7 +105,6 @@ export const mutations: MutationTree<ServerState> = {
|
|||||||
|
|
||||||
state.events.push({
|
state.events.push({
|
||||||
date: date,
|
date: date,
|
||||||
formatTime: formatTime(date),
|
|
||||||
message: message.message,
|
message: message.message,
|
||||||
formatMessage: formatMessage,
|
formatMessage: formatMessage,
|
||||||
type: message.type,
|
type: message.type,
|
||||||
@ -126,7 +125,6 @@ export const mutations: MutationTree<ServerState> = {
|
|||||||
|
|
||||||
state.events.push({
|
state.events.push({
|
||||||
date: payload.date,
|
date: payload.date,
|
||||||
formatTime: formatTime(payload.date),
|
|
||||||
message: payload.message,
|
message: payload.message,
|
||||||
formatMessage: payload.formatMessage,
|
formatMessage: payload.formatMessage,
|
||||||
type: payload.type,
|
type: payload.type,
|
||||||
|
@ -66,7 +66,6 @@ export interface ServerState {
|
|||||||
export interface ServerStateEvent {
|
export interface ServerStateEvent {
|
||||||
date: Date
|
date: Date
|
||||||
time?: number
|
time?: number
|
||||||
formatTime: string
|
|
||||||
type: string
|
type: string
|
||||||
message: string
|
message: string
|
||||||
formatMessage: string | string[]
|
formatMessage: string | string[]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user