Files
akvorado/console/frontend/src/components/InputTimeRange.vue

152 lines
4.3 KiB
Vue

<template>
<div class="grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-1">
<InputListBox
v-model="selectedPreset"
:items="presets"
filter="name"
label="Presets"
class="col-span-2 sm:col-span-1"
>
<template #selected>{{ selectedPreset.name }}</template>
<template #item="{ name }">{{ name }}</template>
</InputListBox>
<InputString v-model="startTime" label="Start" :error="startTimeError" />
<InputString v-model="endTime" label="End" :error="endTimeError" />
</div>
</template>
<script setup>
const props = defineProps({
modelValue: {
// start: start time
// end: end time
// errors: is there an input error?
type: Object,
required: true,
},
});
const emit = defineEmits(["update:modelValue"]);
import { ref, computed, watch } from "vue";
import { Date as SugarDate } from "sugar-date";
import InputString from "@/components/InputString.vue";
import InputListBox from "@/components/InputListBox.vue";
import { isEqual } from "lodash-es";
const startTime = ref("");
const endTime = ref("");
const parsedStartTime = computed(() => SugarDate.create(startTime.value));
const parsedEndTime = computed(() => SugarDate.create(endTime.value));
const startTimeError = computed(() =>
isNaN(parsedStartTime.value) ? "Invalid date" : ""
);
const endTimeError = computed(
() =>
(isNaN(parsedEndTime.value) ? "Invalid date" : "") ||
(!isNaN(parsedStartTime.value) &&
parsedStartTime.value > parsedEndTime.value &&
"End date should be before start date") ||
""
);
const hasErrors = computed(
() => !!(startTimeError.value || endTimeError.value)
);
const presets = [
{ name: "Custom" },
{ name: "Last hour", start: "1 hour ago", end: "now" },
{ name: "Last 6 hours", start: "6 hours ago", end: "now" },
{ name: "Last 12 hours", start: "12 hours ago", end: "now" },
{ name: "Last 24 hours", start: "24 hours ago", end: "now" },
{ name: "Last evening", start: "yesterday at 7pm", end: "today at 1am" },
{ name: "Last 2 days", start: "2 days ago", end: "now" },
{ name: "Last 7 days", start: "7 days ago", end: "now" },
{ name: "Last 30 days", start: "30 days ago", end: "now" },
{ name: "Last 3 months", start: "3 months ago", end: "now" },
{ name: "Last 6 months", start: "6 months ago", end: "now" },
{ name: "Last year", start: "1 year ago", end: "now" },
{ name: "Last 2 years", start: "2 years ago", end: "now" },
{ name: "Last 5 years", start: "5 years ago", end: "now" },
{ name: "Today", start: "today", end: "end of today" },
{ name: "Yesterday", start: "yesterday", end: "end of yesterday" },
{
name: "Day before yesterday",
start: "day before yesterday",
end: "yesterday",
},
{
name: "This week",
start: "the beginning of this week",
end: "the end of this week",
},
{
name: "This month",
start: "the beginning of this month",
end: "the end of this month",
},
{
name: "This year",
start: "the beginning of this year",
end: "the end of this year",
},
{
name: "This day last week",
start: "1 week from today",
end: "6 days from today",
},
{
name: "Previous week",
start: "the beginning of last week",
end: "the end of last week",
},
{
name: "Previous month",
start: "the beginning of last month",
end: "the end of last month",
},
{
name: "Previous year",
start: "the beginning of last year",
end: "the end of last year",
},
].map((v, idx) => ({ id: idx + 1, ...v }));
const selectedPreset = ref(presets[0]);
watch(selectedPreset, (preset) => {
if (preset.start) {
startTime.value = preset.start;
endTime.value = preset.end;
}
});
watch(
() => props.modelValue,
(m) => {
startTime.value = m.start;
endTime.value = m.end;
},
{ immediate: true, deep: true }
);
watch(
[startTime, endTime, hasErrors],
([start, end, errors]) => {
// Find the right preset
const newPreset =
presets.find((p) => p.start === start && p.end === end) || presets[0];
if (newPreset.id !== selectedPreset.value.id) {
selectedPreset.value = newPreset;
}
// Update the model
const newModel = {
start,
end,
errors,
};
if (!isEqual(newModel, props.modelValue)) {
emit("update:modelValue", newModel);
}
},
{ immediate: true }
);
</script>