Skip to content

Commit

Permalink
feat(tracing): skeleton and reactivity fix (#1828)
Browse files Browse the repository at this point in the history
* feat(tracing): skeleton and reactivity fix

* fix: address comments
  • Loading branch information
sumimakito authored Dec 3, 2024
1 parent aeae683 commit c9f624a
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 40 deletions.
53 changes: 42 additions & 11 deletions packages/core/tracing/sandbox/pages/TraceViewerPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,55 @@
@click="slideoutVisible = true"
>
<div>
Click to show the slideout
Click anywhere to show the slideout<br>
Slideout overlay is OFF (not a bug)<br>
Click the close button to dismiss the slideout (not a bug)<br>
</div>
</div>

<KSlideout
class="trace-viewer-slideout"
:close-on-blur="false"
:has-overlay="false"
max-width="min(100%, 1020px)"
:visible="slideoutVisible"
@close="slideoutVisible = false"
>
<template #title>
<KBadge appearance="success">
200
</KBadge>
<template v-if="showSkeleton">
<KSkeletonBox
height="2"
width="50"
/>
</template>
<template v-else>
<KBadge appearance="success">
200
</KBadge>

<div class="trace-viewer-title-request-line">
GET /kong
</div>
<div class="trace-viewer-title-request-line">
GET /kong
</div>
</template>
</template>

<TraceViewer
:config="config"
:root-span="spanRoots[0]"
:show-skeleton="showSkeleton"
:url="url"
/>
</KSlideout>

<KCard
class="controls"
title="Controls"
>
<KInputSwitch
v-model="showSkeleton"
label="Skeleton"
/>
</KCard>
</template>

<script setup lang="ts">
Expand All @@ -42,6 +65,7 @@ const controlPlaneId = import.meta.env.VITE_KONNECT_CONTROL_PLANE_ID || ''
const spanRoots = computed(() => buildSpanTrees(rawSpans))
// const spanRoots = computed(() => buildSpanTrees(mergeSpansInTraceBatches(traceBatches)))
const showSkeleton = ref(false)
const slideoutVisible = ref(false)
const config: TraceViewerConfig = {
Expand Down Expand Up @@ -69,10 +93,7 @@ const url = `https://example.com${path}`
left: 0;
width: 100dvw;
height: 100dvh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 16px;
}
.trace-viewer-slideout {
Expand All @@ -88,11 +109,21 @@ const url = `https://example.com${path}`
.slideout-title {
flex-shrink: 1;
min-width: 0;
height: $kui-line-height-50;
}
.slideout-content {
flex-grow: 1;
}
}
}
.controls {
z-index: 10000;
bottom: 16px;
left: 16px;
margin-bottom: 16px;
position: fixed;
width: auto;
}
</style>
20 changes: 19 additions & 1 deletion packages/core/tracing/sandbox/pages/WaterfallPage.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
<template>
<KCard
class="controls"
title="Controls"
>
<KInputSwitch
v-model="showSkeleton"
label="Skeleton"
/>
</KCard>

<WaterfallView
v-for="(root, i) in spanRoots"
:key="i"
:root-span="root"
:show-skeleton="showSkeleton"
/>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { computed, ref } from 'vue'
import { buildSpanTrees, WaterfallView } from '../../src'
import rawSpans from '../fixtures/spans.json'
const showSkeleton = ref(false)
const spanRoots = computed(() => buildSpanTrees(rawSpans))
</script>

<style lang="scss" scoped>
.controls {
margin-bottom: 16px;
}
</style>
59 changes: 40 additions & 19 deletions packages/core/tracing/src/components/trace-viewer/TraceViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,42 @@
min-size="20"
>
<div class="above-waterfall">
<WaterfallLegend />

<div
v-if="url"
class="url"
>
<div class="label">
{{ t('trace_viewer.url') }}
</div>
<div class="content">
<KCopy
copy-tooltip="Copy"
:text="url"
truncate
:truncation-limit="48"
/>
<template v-if="showSkeleton">
<KSkeletonBox
height="2"
width="25"
/>
<KSkeletonBox
height="2"
width="25"
/>
</template>
<template v-else>
<WaterfallLegend />

<div
v-if="url"
class="url"
>
<div class="label">
{{ t('trace_viewer.url') }}
</div>
<div class="content">
<KCopy
copy-tooltip="Copy"
:text="url"
truncate
:truncation-limit="48"
/>
</div>
</div>
</div>
</template>
</div>

<div class="waterfall-wrapper">
<WaterfallView
:root-span="props.rootSpan"
:show-skeleton="props.showSkeleton"
@update:selected-span="handleUpdateSelectedSpan"
/>
</div>
Expand All @@ -40,8 +53,15 @@
class="detail-pane"
size="50"
>
<template v-if="showSkeleton">
<KSkeleton
:table-columns="2"
:table-rows="8"
type="table"
/>
</template>
<div
v-if="selectedSpan && !spanNothingToDisplay"
v-else-if="selectedSpan && !spanNothingToDisplay"
class="span-details"
>
<SpanEventList
Expand Down Expand Up @@ -85,8 +105,9 @@ const { i18n: { t } } = composables.useI18n()
const props = defineProps<{
config: TraceViewerConfig
rootSpan: SpanNode
rootSpan?: SpanNode
url?: string
showSkeleton?: boolean
}>()
// Provide the config to all children components
Expand Down
38 changes: 29 additions & 9 deletions packages/core/tracing/src/components/waterfall/WaterfallView.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
<template>
<div class="waterfall">
<div
v-if="showSkeleton"
class="waterfall-skeleton"
>
<KSkeleton
v-for="i in 4"
:key="i"
/>
</div>
<div
v-else
class="waterfall"
>
<div class="waterfall-sticky-header">
<!-- RESERVED: ZOOMING
<div class="waterfall-row">
Expand Down Expand Up @@ -75,11 +87,11 @@
// RESERVED: Only used when zooming is enabled
// import { useWheel } from '@vueuse/gesture'
import { AddIcon, RemoveIcon } from '@kong/icons'
import { provide, reactive, ref, useTemplateRef, watch, type PropType, type Ref } from 'vue'
import { computed, provide, reactive, ref, toRef, useTemplateRef, watch, type PropType, type Ref } from 'vue'
import composables from '../../composables'
import { WATERFALL_ROW_COLUMN_GAP, WATERFALL_ROW_LABEL_WIDTH, WATERFALL_ROW_PADDING_X, WATERFALL_SPAN_BAR_FADING_WIDTH } from '../../constants'
import { WATERFALL_CONFIG, WATERFALL_ROWS_STATE, WaterfallRowsState } from '../../constants/waterfall'
import { type SpanNode, type WaterfallConfig } from '../../types'
import { type MarkReactiveInputRefs, type SpanNode, type WaterfallConfig } from '../../types'
import WaterfallScale from './WaterfallScale.vue'
import WaterfallSpanRow from './WaterfallSpanRow.vue'
Expand All @@ -95,6 +107,10 @@ const props = defineProps({
type: Object as PropType<SpanNode>,
default: () => undefined,
},
showSkeleton: {
type: Boolean,
default: false,
},
})
const emit = defineEmits<{
Expand All @@ -108,10 +124,10 @@ const spanBarMeasurementRef = useTemplateRef<HTMLElement>('spanBarMeasurement')
const interaction = ref<'scroll' | 'zoom'>('scroll')
const rowsAreaGuideX = ref<number | undefined>(undefined)
const config = reactive<WaterfallConfig>({
ticks: props.ticks,
totalDurationNano: props.rootSpan?.durationNano ?? 0,
startTimeUnixNano: props.rootSpan ? BigInt(props.rootSpan.span.startTimeUnixNano) : 0n,
const config = reactive<MarkReactiveInputRefs<WaterfallConfig, 'ticks' | 'totalDurationNano' | 'startTimeUnixNano'>>({
ticks: toRef(props, 'ticks'), // This will be unwrapped
totalDurationNano: computed(() => props.rootSpan?.durationNano ?? 0), // This will be unwrapped
startTimeUnixNano: computed(() => props.rootSpan ? BigInt(props.rootSpan.span.startTimeUnixNano) : 0n), // This will be unwrapped
zoom: 1,
viewportShift: 0,
viewport: { left: 0, right: 0 },
Expand Down Expand Up @@ -140,8 +156,8 @@ const handleRowsAreaLeave = () => {
rowsAreaGuideX.value = undefined
}
watch(() => props.rootSpan, (span) => {
config.selectedSpan = span
watch(() => props.rootSpan, (rootSpan) => {
config.selectedSpan = rootSpan
}, { immediate: true })
watch(() => config.selectedSpan, (span) => {
Expand Down Expand Up @@ -235,6 +251,10 @@ watch(() => config.selectedSpan, (span) => {
</script>

<style lang="scss" scoped>
.waterfall-skeleton {
padding: $kui-space-20 $kui-space-40;
}
.waterfall {
box-sizing: border-box;
height: 100%;
Expand Down
1 change: 1 addition & 0 deletions packages/core/tracing/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export * from './otlp'
export * from './spans'
export * from './trace-viewer'
export * from './trace'
export * from './utils'
export * from './waterfall'
8 changes: 8 additions & 0 deletions packages/core/tracing/src/types/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Ref } from 'vue'

/**
* MarkReactiveInputRefs is a utility type that selectively wraps some properties in U of T with
* `Ref<...>` to make `reactive(...)` accept refs for those properties, without modifying the original
* shape.
*/
export type MarkReactiveInputRefs<T, U extends keyof T> = { [P in U]: Ref<T[P]> } & Omit<T, U>

0 comments on commit c9f624a

Please sign in to comment.