Skip to content

Commit

Permalink
Add hint for captures
Browse files Browse the repository at this point in the history
  • Loading branch information
Guilhem-lm committed Jan 8, 2025
1 parent 9711315 commit 0499113
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 30 deletions.
3 changes: 2 additions & 1 deletion frontend/src/lib/components/Dev.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,8 @@
triggersCount: triggersCount,
simplifiedPoll: writable(false),
defaultValues: writable(undefined),
captureOn: writable(undefined)
captureOn: writable(undefined),
showCaptureHint: writable(undefined)
})
setContext<FlowEditorContext>('FlowEditorContext', {
selectedId: selectedIdStore,
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/lib/components/FlowBuilder.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@
const history = initHistory($flowStore)
const pathStore = writable<string>(pathStoreInit ?? initialPath)
const captureOn = writable<boolean>(false)
const showCaptureHint = writable<boolean | undefined>(undefined)
const flowInputEditorStateStore = writable<FlowInputEditorState>({
selectedTab: undefined,
editPanelSize: 0,
Expand Down Expand Up @@ -544,7 +545,8 @@
triggersCount,
simplifiedPoll,
defaultValues: writable(undefined),
captureOn
captureOn,
showCaptureHint
})
async function loadTriggers() {
Expand Down Expand Up @@ -1430,6 +1432,7 @@
select('triggers')
selectTrigger(e.detail.kind)
captureOn.set(true)
showCaptureHint.set(true)
}}
bind:this={flowPreviewButtons}
/>
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/lib/components/ScriptBuilder.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,15 @@
const triggerDefaultValuesStore = writable<Record<string, any> | undefined>(undefined)
const captureOn = writable<boolean | undefined>(undefined)
const showCaptureHint = writable<boolean | undefined>(undefined)
setContext<TriggerContext>('TriggerContext', {
selectedTrigger: selectedTriggerStore,
primarySchedule: primaryScheduleStore,
triggersCount,
simplifiedPoll,
defaultValues: triggerDefaultValuesStore,
captureOn: captureOn
captureOn: captureOn,
showCaptureHint: showCaptureHint
})
const enterpriseLangs = ['bigquery', 'snowflake', 'mssql']
Expand Down
66 changes: 66 additions & 0 deletions frontend/src/lib/components/common/button/PulseButton.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<script>
export let pulseDuration = 1000
let pulseCount = 0
let isPulsing = false
export function triggerPulse(count) {
pulseCount = count
if (!isPulsing) {
isPulsing = true
startPulse()
}
}
function startPulse() {
const interval = setInterval(() => {
if (pulseCount <= 0) {
clearInterval(interval)
isPulsing = false
} else {
pulseCount--
}
}, pulseDuration)
}
</script>

<div class="relative">
<div
class={`pulse ${pulseCount > 0 ? 'active' : ''}`}
style={`--pulse-duration: ${pulseDuration}ms`}
/>
<slot />
</div>

<style>
.pulse {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
background: radial-gradient(circle, rgba(0, 98, 255, 0.4) 0%, transparent 100%);
border-radius: 50%;
transform: translate(-50%, -50%) scale(1);
z-index: 0;
pointer-events: none;
opacity: 0;
}
.pulse.active {
animation: pulse var(--pulse-duration) ease-in infinite;
opacity: 1;
}
@keyframes pulse {
0% {
transform: translate(-50%, -50%) scale(1);
opacity: 0.8;
}
100% {
transform: translate(-50%, -50%) scale(4);
opacity: 0;
}
}
</style>
3 changes: 2 additions & 1 deletion frontend/src/lib/components/details/DetailPageLayout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
triggersCount,
simplifiedPoll,
defaultValues: writable(undefined),
captureOn: writable(undefined)
captureOn: writable(undefined),
showCaptureHint: writable(undefined)
})
</script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
flowInputEditorState
} = getContext<FlowEditorContext>('FlowEditorContext')
const { selectedTrigger, defaultValues, captureOn } = getContext<TriggerContext>('TriggerContext')
const { selectedTrigger, defaultValues, captureOn, showCaptureHint } =
getContext<TriggerContext>('TriggerContext')
function checkDup(modules: FlowModule[]): string | undefined {
let seenModules: string[] = []
for (const m of modules) {
Expand Down Expand Up @@ -78,6 +79,7 @@
selectedTrigger.set(ev.detail.kind)
defaultValues.set(ev.detail.config)
captureOn.set(true)
showCaptureHint.set(true)
}}
on:applyArgs
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
triggersCount: triggersCount,
simplifiedPoll: writable(false),
defaultValues: writable(undefined),
captureOn: writable(undefined)
captureOn: writable(undefined),
showCaptureHint: writable(undefined)
})
async function loadFlow(path: string) {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/lib/components/triggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type TriggerContext = {
simplifiedPoll: Writable<boolean | undefined>
defaultValues: Writable<Record<string, any> | undefined>
captureOn: Writable<boolean | undefined>
showCaptureHint: Writable<boolean | undefined>
}

export function setScheduledPollSchedule(
Expand Down
57 changes: 37 additions & 20 deletions frontend/src/lib/components/triggers/CaptureSection.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@
<script lang="ts">
import { slide } from 'svelte/transition'
import AnimatedButton from '../common/button/AnimatedButton.svelte'
import PulseButton from '../common/button/PulseButton.svelte'
import Button from '../common/button/Button.svelte'
import { CircleStop } from 'lucide-svelte'
import ConnectionIndicator, {
type ConnectionInfo
} from '../common/alert/ConnectionIndicator.svelte'
import CaptureTable from './CaptureTable.svelte'
import { createEventDispatcher, onDestroy } from 'svelte'
import { createEventDispatcher, onDestroy, getContext } from 'svelte'
import type { CaptureTriggerKind } from '$lib/gen'
import CaptureIcon from './CaptureIcon.svelte'
import Tooltip from '../Tooltip.svelte'
import type { TriggerContext } from '$lib/components/triggers'
export let disabled: boolean
export let captureType: CaptureTriggerKind
export let captureInfo: CaptureInfo
Expand All @@ -32,6 +34,8 @@
updateSchema: { payloadData: Record<string, any>; redirect: boolean }
}>()
const { showCaptureHint } = getContext<TriggerContext>('TriggerContext')
onDestroy(() => {
if (captureInfo.active) {
dispatch('captureToggle')
Expand All @@ -44,31 +48,44 @@
redirect: e.detail.redirect
})
}
let pulseButton: PulseButton | undefined
function updateShowCaptureHint(show: boolean | undefined) {
if (show) {
$showCaptureHint = false
setTimeout(() => {
pulseButton?.triggerPulse(1)
}, 200)
}
}
$: updateShowCaptureHint($showCaptureHint)
</script>

<div transition:slide class="pb-12">
<div class="border p-4 rounded-lg">
<div class="flex flex-col gap-1 mb-4">
<div class="flex flex-row items-center justify-start gap-1">
<AnimatedButton animate={captureInfo.active} baseRadius="6px" wrapperClasses="ml-[-2px]">
<Button
size="xs2"
on:click={() => dispatch('captureToggle')}
variant="border"
{disabled}
color="light"
btnClasses={captureInfo.active ? 'text-blue-500 hover:text-blue-500' : ''}
>
<div class="flex flex-row items-center gap-1 w-28 justify-center">
{#if captureInfo.active}
<CircleStop size={14} />
{:else}
<CaptureIcon variant="redDot" size={14} />
{/if}
{captureInfo.active ? 'Stop' : 'Start capturing'}
</div>
</Button>
</AnimatedButton>
<PulseButton bind:this={pulseButton} pulseDuration={800}>
<AnimatedButton animate={captureInfo.active} baseRadius="6px" wrapperClasses="ml-[-2px]">
<Button
size="xs2"
on:click={() => dispatch('captureToggle')}
variant="border"
{disabled}
color="light"
btnClasses={captureInfo.active ? 'text-blue-500 hover:text-blue-500' : ''}
>
<div class="flex flex-row items-center gap-1 w-28 justify-center">
{#if captureInfo.active}
<CircleStop size={14} />
{:else}
<CaptureIcon variant="redDot" size={14} />
{/if}
{captureInfo.active ? 'Stop' : 'Start capturing'}
</div>
</Button>
</AnimatedButton>
</PulseButton>

{#if captureInfo.active}
<ConnectionIndicator connectionInfo={captureInfo.connectionInfo} />
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/lib/components/triggers/CaptureTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
let hasAlreadyFailed = false
export async function loadCaptures(refresh?: boolean) {
console.log('dbg: loadCaptures', refresh)
hasMore = false
try {
Expand Down Expand Up @@ -125,7 +124,6 @@
}
function deselect() {
if (!selected) return
selected = undefined
dispatch('select', undefined)
}
Expand Down Expand Up @@ -153,6 +151,8 @@
deselect()
}
}
let firstClick = true
</script>

<svelte:window on:keydown={handleKeydown} />
Expand Down Expand Up @@ -186,6 +186,10 @@
class={twMerge('grow min-h-0', captures.length > 7 ? 'h-[300px]' : 'h-auto')}
use:clickOutside={{ capture: false, exclude: getPropPickerElements }}
on:click_outside={() => {
if (firstClick) {
firstClick = false
return
}
deselect()
}}
>
Expand Down Expand Up @@ -292,7 +296,6 @@
if (isFlow && testKind === 'main') {
dispatch('testWithArgs', payloadData)
} else {
console.log('dbg: applyArgs from table', payloadData)
dispatch('applyArgs', {
kind: testKind,
args: payloadData
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/routes/flows/dev/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@
triggersCount: triggersCount,
simplifiedPoll: writable(false),
defaultValues: writable(undefined),
captureOn: writable(undefined)
captureOn: writable(undefined),
showCaptureHint: writable(undefined)
})
setContext<FlowEditorContext>('FlowEditorContext', {
Expand Down

0 comments on commit 0499113

Please sign in to comment.