✨ (theme) Add progress bar option (#1276)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced progress bar functionality across various components for a more interactive user experience. - Added progress tracking and display in chat sessions. - **Enhancements** - Adjusted layout height calculations in the settings and theme pages for consistency. - Improved theme customization options with progress bar styling and placement settings. - **Bug Fixes** - Fixed dynamic height calculation issues in settings and theme side menus by standardizing heights. - **Style** - Added custom styling properties for the progress bar in chat interfaces. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { LiteBadge } from './LiteBadge'
|
||||
import { createEffect, createSignal, onCleanup, onMount, Show } from 'solid-js'
|
||||
import { isNotDefined, isNotEmpty } from '@typebot.io/lib'
|
||||
import { isDefined, isNotDefined, isNotEmpty } from '@typebot.io/lib'
|
||||
import { startChatQuery } from '@/queries/startChatQuery'
|
||||
import { ConversationContainer } from './ConversationContainer'
|
||||
import { setIsMobile } from '@/utils/isMobileSignal'
|
||||
@@ -18,6 +18,7 @@ import { defaultTheme } from '@typebot.io/schemas/features/typebot/theme/constan
|
||||
import { clsx } from 'clsx'
|
||||
import { HTTPError } from 'ky'
|
||||
import { injectFont } from '@/utils/injectFont'
|
||||
import { ProgressBar } from './ProgressBar'
|
||||
|
||||
export type BotProps = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -129,6 +130,14 @@ export const Bot = (props: BotProps & { class?: string }) => {
|
||||
createEffect(() => {
|
||||
if (isNotDefined(props.typebot) || typeof props.typebot === 'string') return
|
||||
setCustomCss(props.typebot.theme.customCss ?? '')
|
||||
if (
|
||||
props.typebot.theme.general?.progressBar?.isEnabled &&
|
||||
initialChatReply() &&
|
||||
!initialChatReply()?.typebot.theme.general?.progressBar?.isEnabled
|
||||
) {
|
||||
setIsInitialized(false)
|
||||
initializeBot().then()
|
||||
}
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
@@ -190,6 +199,9 @@ type BotContentProps = {
|
||||
}
|
||||
|
||||
const BotContent = (props: BotContentProps) => {
|
||||
const [progressValue, setProgressValue] = createSignal<number | undefined>(
|
||||
props.initialChatReply.progress
|
||||
)
|
||||
let botContainer: HTMLDivElement | undefined
|
||||
|
||||
const resizeObserver = new ResizeObserver((entries) => {
|
||||
@@ -207,7 +219,11 @@ const BotContent = (props: BotContentProps) => {
|
||||
defaultTheme.general.font
|
||||
)
|
||||
if (!botContainer) return
|
||||
setCssVariablesValue(props.initialChatReply.typebot.theme, botContainer)
|
||||
setCssVariablesValue(
|
||||
props.initialChatReply.typebot.theme,
|
||||
botContainer,
|
||||
props.context.isPreview
|
||||
)
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
@@ -223,6 +239,14 @@ const BotContent = (props: BotContentProps) => {
|
||||
props.class
|
||||
)}
|
||||
>
|
||||
<Show
|
||||
when={
|
||||
isDefined(progressValue()) &&
|
||||
props.initialChatReply.typebot.theme.general?.progressBar?.isEnabled
|
||||
}
|
||||
>
|
||||
<ProgressBar value={progressValue() as number} />
|
||||
</Show>
|
||||
<div class="flex w-full h-full justify-center">
|
||||
<ConversationContainer
|
||||
context={props.context}
|
||||
@@ -231,6 +255,7 @@ const BotContent = (props: BotContentProps) => {
|
||||
onAnswer={props.onAnswer}
|
||||
onEnd={props.onEnd}
|
||||
onNewLogs={props.onNewLogs}
|
||||
onProgressUpdate={setProgressValue}
|
||||
/>
|
||||
</div>
|
||||
<Show
|
||||
|
||||
@@ -64,6 +64,7 @@ type Props = {
|
||||
onAnswer?: (answer: { message: string; blockId: string }) => void
|
||||
onEnd?: () => void
|
||||
onNewLogs?: (logs: OutgoingLog[]) => void
|
||||
onProgressUpdate?: (progress: number) => void
|
||||
}
|
||||
|
||||
export const ConversationContainer = (props: Props) => {
|
||||
@@ -172,6 +173,7 @@ export const ConversationContainer = (props: Props) => {
|
||||
return
|
||||
}
|
||||
if (!data) return
|
||||
if (data.progress) props.onProgressUpdate?.(data.progress)
|
||||
if (data.lastMessageNewFormat) {
|
||||
setFormattedMessages([
|
||||
...formattedMessages(),
|
||||
@@ -269,7 +271,7 @@ export const ConversationContainer = (props: Props) => {
|
||||
return (
|
||||
<div
|
||||
ref={chatContainer}
|
||||
class="flex flex-col overflow-y-scroll w-full min-h-full px-3 pt-10 relative scrollable-container typebot-chat-view scroll-smooth gap-2"
|
||||
class="flex flex-col overflow-y-auto w-full min-h-full px-3 pt-10 relative scrollable-container typebot-chat-view scroll-smooth gap-2"
|
||||
>
|
||||
<For each={chatChunks()}>
|
||||
{(chatChunk, index) => (
|
||||
|
||||
14
packages/embeds/js/src/components/ProgressBar.tsx
Normal file
14
packages/embeds/js/src/components/ProgressBar.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
type Props = {
|
||||
value: number
|
||||
}
|
||||
|
||||
export const ProgressBar = (props: Props) => (
|
||||
<div class="typebot-progress-bar-container">
|
||||
<div
|
||||
class="typebot-progress-bar"
|
||||
style={{
|
||||
width: `${props.value}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
Reference in New Issue
Block a user