This commit is contained in:
162
client/src/components/duration-control.vue
Normal file
162
client/src/components/duration-control.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div>
|
||||
<template>
|
||||
<v-row dense>
|
||||
<v-col
|
||||
><span class="text-caption">
|
||||
{{ label }}
|
||||
</span></v-col
|
||||
>
|
||||
<v-col cols="3">
|
||||
<v-text-field
|
||||
v-show="showDays"
|
||||
ref="daysPicker"
|
||||
dense
|
||||
:value="splitSpan.days"
|
||||
:readonly="readonly"
|
||||
:disabled="disabled"
|
||||
:label="$sock.t('TimeSpanDays')"
|
||||
type="number"
|
||||
:data-cy="`${dataCy}:days`"
|
||||
:error="!!hasErrors"
|
||||
@input="updateSpan()"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="3">
|
||||
<v-text-field
|
||||
ref="hoursPicker"
|
||||
dense
|
||||
:value="splitSpan.hours"
|
||||
:readonly="readonly"
|
||||
:disabled="disabled"
|
||||
:label="$sock.t('TimeSpanHours')"
|
||||
type="number"
|
||||
:data-cy="`${dataCy}:hours`"
|
||||
:error="!!hasErrors"
|
||||
@input="updateSpan()"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="3">
|
||||
<v-text-field
|
||||
ref="minutesPicker"
|
||||
dense
|
||||
:value="splitSpan.minutes"
|
||||
:readonly="readonly"
|
||||
:disabled="disabled"
|
||||
:label="$sock.t('TimeSpanMinutes')"
|
||||
type="number"
|
||||
:data-cy="`${dataCy}:minutes`"
|
||||
:error="!!hasErrors"
|
||||
@input="updateSpan()"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="3">
|
||||
<v-text-field
|
||||
v-show="showSeconds"
|
||||
ref="secondsPicker"
|
||||
dense
|
||||
:value="splitSpan.seconds"
|
||||
:readonly="readonly"
|
||||
:disabled="disabled"
|
||||
:label="$sock.t('TimeSpanSeconds')"
|
||||
type="number"
|
||||
:data-cy="`${dataCy}:seconds`"
|
||||
:error="!!hasErrors"
|
||||
@input="updateSpan()"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
<div class="v-messages theme--light error--text mt-n5" role="alert">
|
||||
<div class="v-messages__wrapper">
|
||||
<div class="v-messages__message">{{ allErrors() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
label: { type: String, default: null },
|
||||
rules: { type: Array, default: undefined },
|
||||
errorMessages: { type: Array, default: null },
|
||||
value: { type: String, default: null },
|
||||
readonly: { type: Boolean, default: false },
|
||||
disabled: { type: Boolean, default: false },
|
||||
showSeconds: { type: Boolean, default: true },
|
||||
showDays: { type: Boolean, default: true },
|
||||
dataCy: { type: String, default: null }
|
||||
},
|
||||
computed: {
|
||||
hasErrors() {
|
||||
return this.errorMessages != null && this.errorMessages.length > 0;
|
||||
},
|
||||
splitSpan() {
|
||||
const vm = this;
|
||||
let theDays = 0;
|
||||
let theHours = 0;
|
||||
let theMinutes = 0;
|
||||
let theSeconds = 0;
|
||||
|
||||
if (vm.value == null) {
|
||||
theDays = 0;
|
||||
theHours = 0;
|
||||
theMinutes = 0;
|
||||
theSeconds = 0;
|
||||
} else {
|
||||
const work = vm.value.split(":");
|
||||
//has days?
|
||||
if (work[0].includes(".")) {
|
||||
const dh = work[0].split(".");
|
||||
theDays = Number(dh[0]);
|
||||
theHours = Number(dh[1]);
|
||||
} else {
|
||||
theHours = Number(work[0]);
|
||||
}
|
||||
theMinutes = Number(work[1]);
|
||||
//has milliseconds? (ignore them)
|
||||
if (work[2].includes(".")) {
|
||||
const dh = work[2].split(".");
|
||||
theSeconds = Number(dh[0]);
|
||||
} else {
|
||||
theSeconds = Number(work[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
days: theDays,
|
||||
hours: theHours,
|
||||
minutes: theMinutes,
|
||||
seconds: theSeconds
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
allErrors() {
|
||||
let ret = "";
|
||||
|
||||
if (this.errorMessages != null && this.errorMessages.length > 0) {
|
||||
ret += this.errorMessages.toString();
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
updateSpan() {
|
||||
let ret = "";
|
||||
//NOTE: even though a user may type a text value into the input, because it's set to "Number"
|
||||
//it always has a value of zero if it's not a digit even though the user typed Q for example (firefox at least)
|
||||
//so no parsing here to handle weird entries is required AFAICT
|
||||
const daysValue = this.$refs.daysPicker.$refs.input.value || 0;
|
||||
const hoursValue = this.$refs.hoursPicker.$refs.input.value || 0;
|
||||
const minutesValue = this.$refs.minutesPicker.$refs.input.value || 0;
|
||||
const secondsValue = this.$refs.secondsPicker.$refs.input.value || 0;
|
||||
|
||||
if (daysValue > 0) {
|
||||
ret = `${daysValue}.`;
|
||||
}
|
||||
|
||||
ret += `${hoursValue}:${minutesValue}:${secondsValue}`;
|
||||
this.$emit("input", ret);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user