Implements comprehensive time filtering and visualization improvements: - Adds time range picker with presets from 5min to 24h - Enhances chart visualization with minute-level granularity - Updates globe visualization to respond to time/filter changes - Implements animated event log display - Swaps primary/secondary color scheme for better contrast Improves realtime data handling with automatic updates and proper cleanup on unmount. Includes i18n support for new time picker UI across all supported languages.
93 lines
1.9 KiB
Vue
93 lines
1.9 KiB
Vue
<script lang="ts" setup>
|
|
import { cn } from '@/lib/utils'
|
|
import { computed, onMounted, ref, useSlots } from 'vue'
|
|
|
|
const props = withDefaults(defineProps<{
|
|
class?: string
|
|
delay?: number
|
|
}>(), {
|
|
delay: 1000,
|
|
})
|
|
|
|
const slots = useSlots()
|
|
const index = ref(0)
|
|
const slotsArray = ref<any>([])
|
|
const maxShowItems = 100
|
|
|
|
const itemsToShow = computed(() => {
|
|
const start = index.value - maxShowItems < 0 ? 0 : index.value - maxShowItems
|
|
return slotsArray.value.slice(start, index.value)
|
|
})
|
|
|
|
async function loadComponents() {
|
|
slotsArray.value = slots.default ? slots.default()?.[0]?.children : []
|
|
|
|
while (index.value < slotsArray.value.length) {
|
|
index.value++
|
|
await delay(props.delay)
|
|
}
|
|
}
|
|
|
|
async function delay(ms: number) {
|
|
return new Promise(resolve => setTimeout(resolve, ms))
|
|
}
|
|
|
|
function getInitial(idx: number) {
|
|
return idx === index.value - 1
|
|
? {
|
|
scale: 0,
|
|
opacity: 0,
|
|
}
|
|
: undefined
|
|
}
|
|
function getEnter(idx: number) {
|
|
return idx === index.value - 1
|
|
? {
|
|
scale: 1,
|
|
opacity: 1,
|
|
y: 0,
|
|
transition: {
|
|
type: 'spring',
|
|
stiffness: 250,
|
|
damping: 40,
|
|
},
|
|
}
|
|
: undefined
|
|
}
|
|
|
|
function getLeave() {
|
|
return {
|
|
scale: 0,
|
|
opacity: 0,
|
|
y: 0,
|
|
transition: {
|
|
type: 'spring',
|
|
stiffness: 350,
|
|
damping: 40,
|
|
},
|
|
}
|
|
};
|
|
|
|
onMounted(() => loadComponents())
|
|
</script>
|
|
|
|
<template>
|
|
<div :class="cn('overflow-auto', $props.class)">
|
|
<transition-group name="list" tag="div" class="flex flex-col-reverse items-center p-2" move-class="move">
|
|
<div
|
|
v-for="(item, idx) in itemsToShow"
|
|
:key="item.props.key"
|
|
v-motion :initial="getInitial(idx)" :enter="getEnter(idx)" :leave="getLeave()"
|
|
:class="cn('mx-auto w-full')"
|
|
>
|
|
<component :is="item" />
|
|
</div>
|
|
</transition-group>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.move {
|
|
transition: transform 0.4s ease-out;
|
|
}
|
|
</style>
|