Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add layout and hide edges options to timeline #1135

Merged
merged 2 commits into from
Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"vue-router": "^4.0.12"
},
"dependencies": {
"@prefecthq/graphs": "0.1.15",
"@prefecthq/graphs": "0.1.16",
"@prefecthq/radar": "0.0.19",
"@prefecthq/vue-charts": "0.0.19",
"axios": "0.27.2",
Expand Down
85 changes: 71 additions & 14 deletions src/components/FlowRunTimeline.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
<template>
<div class="flow-run-timeline">
<div v-if="graphData.length > 0" class="flow-run-timeline__container">
<div class="flow-run-timeline__options">
<FlowRunTimelineOptions
:layout="layout"
:hide-edges="hideEdges"
@update:layout="updateLayout"
@update:hide-edges="updateHideEdges"
/>
</div>
<div v-if="graphData.length > 0" class="flow-run-timeline__graph-wrapper">
<FlowRunTimeline
class="flow-run-timeline__timeline"
:class="{ 'flow-run-timeline__timeline--panel-open': showTaskRunPanel }"
class="flow-run-timeline__graph"
:class="{ 'flow-run-timeline__graph--panel-open': showTaskRunPanel }"
:graph-data="graphData"
:layout="layout"
:hide-edges="hideEdges"
:is-running="isRunning"
:format-date-fns="formatDateFns"
:selected-node-id="selectedNode"
:theme="theme"
layout="nearestParent"
:selected-node-id="selectedNode"
@click="selectNode"
/>
</div>
Expand All @@ -26,11 +35,19 @@
</template>

<script lang="ts" setup>
import { FlowRunTimeline, FormatDateFns, HSL, ThemeStyleOverrides, TimelineNodeData, TimelineThemeOptions } from '@prefecthq/graphs'
import {
FlowRunTimeline,
FormatDateFns,
HSL,
ThemeStyleOverrides,
TimelineNodeData,
TimelineNodesLayoutOptions,
TimelineThemeOptions
} from '@prefecthq/graphs'
import { useColorTheme } from '@prefecthq/prefect-design'
import { useSubscription } from '@prefecthq/vue-compositions'
import { computed, Ref, ref } from 'vue'
import { TaskRunPanel } from '@/components'
import { computed, Ref, ref, watch } from 'vue'
import { TaskRunPanel, FlowRunTimelineOptions } from '@/components'
import { useWorkspaceApi } from '@/compositions'
import { FlowRun, isValidTimelineNodeData } from '@/models'
import { formatTimeNumeric, formatTimeShortNumeric, formatDate } from '@/utilities'
Expand All @@ -41,13 +58,20 @@

const { value: colorThemeValue } = useColorTheme()

const defaultOptionThresholds = {
nearestParentLayout: 100,
hideEdges: 40,
}

const showTaskRunPanel = ref(false)
const selectedNode: Ref<string | null> = ref(null)
const formatDateFns: FormatDateFns = {
timeBySeconds: formatTimeNumeric,
timeByMinutes: formatTimeShortNumeric,
date: formatDate,
}
const layout: Ref<TimelineNodesLayoutOptions> = ref('nearestParent')
const hideEdges = ref(false)

const selectNode = (value: string | null): void => {
if (!value || value === selectedNode.value) {
Expand All @@ -60,10 +84,18 @@
showTaskRunPanel.value = true
}

const closePanel = (): void => {
function closePanel(): void {
showTaskRunPanel.value = false
}

function updateLayout(value: TimelineNodesLayoutOptions): void {
layout.value = value
}

function updateHideEdges(value: boolean): void {
hideEdges.value = value
}

const isRunning = computed(() => {
return props.flowRun.state?.name.toLowerCase() === 'running'
})
Expand All @@ -86,10 +118,27 @@
return items
})

const unwatchInitialData = watch(graphData, (value) => {
if (value.length > 0) {
if (value.length > defaultOptionThresholds.nearestParentLayout) {
layout.value = 'waterfall'
}

if (value.length > defaultOptionThresholds.hideEdges) {
hideEdges.value = true
}

unwatchInitialData()
}
})

/*
* Theme overrides
*/
const documentStyles = getComputedStyle(document.documentElement)
const bodyStyles = getComputedStyle(document.body)

const getStateColor = (cssVariable: string): string => {
function getStateColor(cssVariable: string): string {
return bodyStyles.getPropertyValue(cssVariable).trim()
}

Expand All @@ -116,7 +165,7 @@
alphaNodeDimmed: 0.2,
}))

const getHslColor = (defaultCssVariable: string, darkCssVariable?: string): HSL => {
function getHslColor(defaultCssVariable: string, darkCssVariable?: string): HSL {
const propertyValue = darkCssVariable && colorThemeValue.value === 'dark'
? darkCssVariable
: defaultCssVariable
Expand Down Expand Up @@ -145,23 +194,31 @@
.flow-run-timeline { @apply
flex
overflow-hidden
relative
}

.flow-run-timeline__options { @apply
absolute
bottom-1
right-1
z-10
}

.flow-run-timeline__container { @apply
.flow-run-timeline__graph-wrapper { @apply
h-[320px]
w-full
relative
overflow-hidden
}

.flow-run-timeline__timeline { @apply
.flow-run-timeline__graph { @apply
bg-background-600
dark:bg-background
rounded-lg
}

@media (min-width: 640px) {
.flow-run-timeline__timeline--panel-open {
.flow-run-timeline__graph--panel-open {
width: calc(100% - 320px);
}
}
Expand Down
91 changes: 91 additions & 0 deletions src/components/FlowRunTimelineOptions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<template>
<p-pop-over
pleek91 marked this conversation as resolved.
Show resolved Hide resolved
ref="popOver"
class="flow-run-timeline-options"
auto-close
:placement="placement"
>
<template #target="{ toggle }">
<p-button
ref="settingsButton"
aria-label="Flow Run Timeline Options"
icon="CogIcon"
flat
@click="toggle"
/>
</template>
<div class="flow-run-timeline-options__popover">
<p-overflow-menu>
<div class="flow-run-timeline-options__popover-option-set">
pleek91 marked this conversation as resolved.
Show resolved Hide resolved
<p-radio-group v-model="layoutModel" :options="layoutOptions">
<template #label="{ option }">
{{ option.label }}
</template>
</p-radio-group>
</div>
<div class="flow-run-timeline-options__popover-option-set">
<p-checkbox v-model="hideDependencyArrowsModel" label="Hide Dependency Arrows" />
</div>
</p-overflow-menu>
</div>
</p-pop-over>
</template>

<script lang="ts" setup>
import { TimelineNodesLayoutOptions } from '@prefecthq/graphs'
import { PButton, positions, PPopOver } from '@prefecthq/prefect-design'
import { computed, ref } from 'vue'

const props = defineProps<{
layout: TimelineNodesLayoutOptions,
hideEdges: boolean,
}>()

const emit = defineEmits<{
(event: 'update:layout', value: TimelineNodesLayoutOptions): void,
(event: 'update:hideEdges', value: boolean): void,
}>()

const settingsButton = ref<typeof PButton>()
const popOver = ref<typeof PPopOver>()
brandonreid marked this conversation as resolved.
Show resolved Hide resolved
const placement = [positions.topRight, positions.bottomRight, positions.topLeft, positions.bottomLeft]

const layoutOptions: {
value: TimelineNodesLayoutOptions,
label: string,
}[] = [
{
value: 'nearestParent',
label: 'Nearest Parent Layout',
}, {
value: 'waterfall',
label: 'Waterfall Layout (fast)',
},
]
const layoutModel = computed({
get: () => props.layout,
set: (layout: TimelineNodesLayoutOptions) => emit('update:layout', layout),
brandonreid marked this conversation as resolved.
Show resolved Hide resolved
})

const hideDependencyArrowsModel = computed({
get: () => props.hideEdges,
set: () => emit('update:hideEdges', !props.hideEdges),
})
</script>

<style>
.flow-run-timeline-options { @apply
inline-block
}

.flow-run-timeline-options__popover { @apply
py-1
}

.flow-run-timeline-options__popover-option-set { @apply
p-3
}
.flow-run-timeline-options__popover-option-set label { @apply
cursor-pointer
}
brandonreid marked this conversation as resolved.
Show resolved Hide resolved
</style>
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export { default as FlowRunTagsInput } from './FlowRunTagsInput.vue'
export { default as FlowRunTaskCount } from './FlowRunTaskCount.vue'
export { default as FlowRunTaskRuns } from './FlowRunTaskRuns.vue'
export { default as FlowRunTimeline } from './FlowRunTimeline.vue'
export { default as FlowRunTimelineOptions } from './FlowRunTimelineOptions.vue'
export { default as FlowsDeleteButton } from './FlowsDeleteButton.vue'
export { default as FlowsPageEmptyState } from './FlowsPageEmptyState.vue'
export { default as FlowsTable } from './FlowsTable.vue'
Expand Down