mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 00:02:30 +00:00
* feat: flow chat job-backed detail, smooth streaming and answer chrome * chore: document setFlowPath, drop unused chatIdentity, tighten comments * fix: read a nested agent tool's call from its own job * fix: show only the model's arguments on a tool card read from its job * feat: add attachments to the chat sdk message type * refactor: read a flow chat message's files from the message, not its run * fix: keep every job-backed answer when reads finish out of order * refactor: build flow chat tool cards from the conversation row alone * feat: keep the model picker's current choice when a flow chat retry replays its run * fix: export ChatAttachment from the chat sdk entry point * fix: drop a conversation list for the flow path before setFlowPath * fix: return the current listing, not old-path rows, after setFlowPath * fix: treat a listing stale on kind or path as one stale listing * revert: drop setFlowPath and rebuild the chat when the flow path changes * fix: refuse a flow chat retry once any turn ran while it read the run * docs: say where a display message's createdAt comes from * style: drop the rule between New chat and the conversation list
67 lines
1.9 KiB
Svelte
67 lines
1.9 KiB
Svelte
<script lang="ts">
|
|
/**
|
|
* A soft edge on a scroller, so content scrolling out of view fades instead of being
|
|
* cut against whatever borders it.
|
|
*
|
|
* Rendered as an overlay in the scroller's positioned ancestor rather than inside the
|
|
* scroller: `sticky` would resolve against the scroller's padding box and leave the
|
|
* first few pixels unfaded. It shows only when there is something hidden in that
|
|
* direction, so a transcript that fits shows no edge at all.
|
|
*/
|
|
import { twMerge } from 'tailwind-merge'
|
|
|
|
interface Props {
|
|
/** The scrolling element this masks. */
|
|
scroller: HTMLElement | undefined
|
|
edge?: 'top' | 'bottom'
|
|
/** Tailwind colour stop to fade from — the surface the scroller sits on. */
|
|
from?: string
|
|
/** Tailwind height of the fade band. */
|
|
height?: string
|
|
class?: string
|
|
}
|
|
|
|
let {
|
|
scroller,
|
|
edge = 'top',
|
|
from = 'from-surface',
|
|
height = 'h-4',
|
|
class: className = ''
|
|
}: Props = $props()
|
|
|
|
let hidden = $state(true)
|
|
|
|
$effect(() => {
|
|
const el = scroller
|
|
if (!el) return
|
|
const update = () => {
|
|
// A pixel of slack: fractional scroll offsets otherwise leave the bottom edge
|
|
// showing on a scroller that is already at its end.
|
|
hidden =
|
|
edge === 'top' ? el.scrollTop <= 1 : el.scrollTop + el.clientHeight >= el.scrollHeight - 1
|
|
}
|
|
update()
|
|
el.addEventListener('scroll', update, { passive: true })
|
|
// Content arriving or the pane resizing changes what is hidden without a scroll.
|
|
const observer = new ResizeObserver(update)
|
|
observer.observe(el)
|
|
if (el.firstElementChild) observer.observe(el.firstElementChild)
|
|
return () => {
|
|
el.removeEventListener('scroll', update)
|
|
observer.disconnect()
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<div
|
|
class={twMerge(
|
|
'pointer-events-none absolute inset-x-0 transition-opacity duration-150',
|
|
edge === 'top' ? 'top-0 bg-gradient-to-b' : 'bottom-0 bg-gradient-to-t',
|
|
from,
|
|
'to-transparent',
|
|
height,
|
|
hidden ? 'opacity-0' : 'opacity-100',
|
|
className
|
|
)}
|
|
></div>
|