mirror of https://github.com/buster-so/buster.git
Warning for setup
This commit is contained in:
parent
3656ee586c
commit
33312538e1
|
@ -64,7 +64,7 @@ export const InputTextAreaButton = forwardRef<HTMLTextAreaElement, InputTextArea
|
|||
onClick={onClickBox}
|
||||
className={cn(
|
||||
inputTextAreaButtonVariants({ variant }),
|
||||
'transition-all duration-500 hover:shadow-md focus:shadow-lg',
|
||||
!disabled && 'transition-all duration-500 hover:shadow-md focus:shadow-lg',
|
||||
loading && 'border-border!',
|
||||
className
|
||||
)}>
|
||||
|
|
|
@ -6,6 +6,9 @@ import { useBusterNewChatContextSelector } from '@/context/Chats';
|
|||
import { inputHasText } from '@/lib/text';
|
||||
import { useMemoizedFn, useMount } from '@/hooks';
|
||||
import { ChangeEvent, useMemo, useState } from 'react';
|
||||
import { useGetDatasets } from '@/api/buster_rest';
|
||||
import { NewChatWarning } from './NewChatWarning';
|
||||
import { useNewChatWarning } from './useNewChatWarning';
|
||||
|
||||
const autoResizeConfig = {
|
||||
minRows: 3,
|
||||
|
@ -17,10 +20,12 @@ export const NewChatInput: React.FC<{}> = () => {
|
|||
const [inputValue, setInputValue] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const newChatWarningProps = useNewChatWarning();
|
||||
const { showWarning } = newChatWarningProps;
|
||||
|
||||
const disabledSubmit = useMemo(() => {
|
||||
return !inputHasText(inputValue);
|
||||
}, [inputValue]);
|
||||
return !inputHasText(inputValue) || showWarning;
|
||||
}, [inputValue, showWarning]);
|
||||
|
||||
const onSubmit = useMemoizedFn(async (value: string) => {
|
||||
if (disabledSubmit) return;
|
||||
|
@ -49,17 +54,23 @@ export const NewChatInput: React.FC<{}> = () => {
|
|||
});
|
||||
|
||||
return (
|
||||
<InputTextAreaButton
|
||||
className="transition-all duration-300 hover:shadow-lg active:shadow-md"
|
||||
placeholder="Ask Buster a question..."
|
||||
autoResize={autoResizeConfig}
|
||||
onSubmit={onSubmit}
|
||||
onChange={onChange}
|
||||
onStop={onStop}
|
||||
loading={loading}
|
||||
disabledSubmit={disabledSubmit}
|
||||
autoFocus
|
||||
ref={textAreaRef}
|
||||
/>
|
||||
<div className="flex flex-col space-y-2">
|
||||
<InputTextAreaButton
|
||||
className={
|
||||
!showWarning ? 'transition-all duration-300 hover:shadow-lg active:shadow-md' : ''
|
||||
}
|
||||
placeholder="Ask Buster a question..."
|
||||
autoResize={autoResizeConfig}
|
||||
onSubmit={onSubmit}
|
||||
onChange={onChange}
|
||||
onStop={onStop}
|
||||
loading={loading}
|
||||
disabled={showWarning}
|
||||
disabledSubmit={disabledSubmit}
|
||||
autoFocus
|
||||
ref={textAreaRef}
|
||||
/>
|
||||
{newChatWarningProps.showWarning && <NewChatWarning {...newChatWarningProps} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
import { useGetDatasets } from '@/api/buster_rest';
|
||||
import { useGetDatasource, useListDatasources } from '@/api/buster_rest/data_source';
|
||||
import { cn } from '@/lib/classMerge';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useNewChatWarning } from './useNewChatWarning';
|
||||
import { ArrowUpRight, CircleCheck, CircleXmark } from '@/components/ui/icons';
|
||||
import { Paragraph, Text } from '@/components/ui/typography';
|
||||
import { Button } from '@/components/ui/buttons';
|
||||
import Link from 'next/link';
|
||||
|
||||
export const NewChatWarning = React.memo(({}: ReturnType<typeof useNewChatWarning>) => {
|
||||
const hasDatasources = true;
|
||||
const hasDatasets = false;
|
||||
const allCompleted = hasDatasets && hasDatasources;
|
||||
const progress = [hasDatasources, hasDatasets].filter(Boolean).length;
|
||||
const progressPercentage = (progress / 2) * 100;
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<Text className="text-xl font-medium text-gray-800">Setup Checklist</Text>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="text-sm font-medium text-gray-500">{progress}/2 completed</div>
|
||||
<div className="h-2 w-20 rounded-full bg-gray-100">
|
||||
<div
|
||||
className="h-full rounded-full bg-gray-500 transition-all duration-500 ease-in-out"
|
||||
style={{ width: `${progressPercentage}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<SetupItem
|
||||
number="1"
|
||||
status={hasDatasources}
|
||||
title="Connect a Data Source"
|
||||
description="Link files, databases, or websites to enable knowledge retrieval"
|
||||
link="https://docs.buster.so/docs/using-the-cli/init-command"
|
||||
linkText="Go to docs"
|
||||
/>
|
||||
|
||||
<SetupItem
|
||||
number="2"
|
||||
status={hasDatasets}
|
||||
title="Create a Dataset"
|
||||
description="Organize your information for efficient querying"
|
||||
link="https://docs.buster.so/docs/using-the-cli/create-dataset"
|
||||
linkText="Go to docs"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cn(
|
||||
'mt-5 flex items-center rounded-lg border p-4',
|
||||
allCompleted ? 'border-gray-200 bg-gray-50' : 'border-gray-200 bg-gray-50'
|
||||
)}>
|
||||
<div
|
||||
className={cn(
|
||||
'mr-3 flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full',
|
||||
allCompleted ? 'bg-gray-200' : 'bg-gray-200'
|
||||
)}>
|
||||
{allCompleted ? (
|
||||
<CircleCheck fill="#4B5563" title="Complete" />
|
||||
) : (
|
||||
<div className="h-4 w-4 rounded-full bg-gray-400" />
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<Text className="font-medium text-gray-700">
|
||||
{allCompleted
|
||||
? "You're all set! Ask questions to get answers from your data."
|
||||
: 'Complete both steps to start querying your information.'}
|
||||
</Text>
|
||||
<Text className="text-sm text-gray-500">
|
||||
{allCompleted
|
||||
? ' Your data is ready to be explored.'
|
||||
: " Without proper setup, we can't retrieve relevant information."}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
interface SetupItemProps {
|
||||
number: string;
|
||||
status: boolean;
|
||||
title: string;
|
||||
description: string;
|
||||
link?: string;
|
||||
linkText?: string;
|
||||
}
|
||||
|
||||
const SetupItem = ({ number, status, title, description, link, linkText }: SetupItemProps) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'group relative flex items-start space-x-4 rounded-lg border p-4 transition-all duration-200',
|
||||
status ? 'border-green-700/30 bg-green-50' : 'border-gray-200'
|
||||
)}>
|
||||
<div
|
||||
className={cn(
|
||||
'text-md flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full font-medium',
|
||||
status ? 'bg-green-200 text-green-700' : 'bg-gray-100 text-gray-500'
|
||||
)}>
|
||||
{status ? <CircleCheck title="Complete" /> : number}
|
||||
</div>
|
||||
|
||||
<div className="min-w-0 flex-1 flex-col">
|
||||
<div className="flex items-center justify-between">
|
||||
<Text className="font-medium text-gray-800">{title}</Text>
|
||||
{status && (
|
||||
<span className="rounded-full bg-green-200 px-2 py-1 text-xs font-medium text-green-700">
|
||||
Complete
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Paragraph className="mt-1 text-sm text-gray-600">{description}</Paragraph>
|
||||
|
||||
{link && (
|
||||
<Link href={link} target="_blank">
|
||||
<Button
|
||||
className="mt-2 text-sm"
|
||||
size="tall"
|
||||
suffix={
|
||||
<span className="text-xs">
|
||||
<ArrowUpRight />
|
||||
</span>
|
||||
}>
|
||||
{linkText}
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
import { useGetDatasets } from '@/api/buster_rest';
|
||||
import { useListDatasources } from '@/api/buster_rest/data_source';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const useNewChatWarning = () => {
|
||||
const { data: datasets, isFetched: isDatasetsFetched } = useGetDatasets();
|
||||
const { data: datasources, isFetched: isDatasourcesFetched } = useListDatasources();
|
||||
|
||||
const showWarning = useMemo(() => {
|
||||
return true;
|
||||
if (!isDatasetsFetched || !isDatasourcesFetched) return false;
|
||||
if (datasets?.length === 0) return true;
|
||||
if (datasources?.length === 0) return true;
|
||||
return false;
|
||||
}, [datasets, datasources, isDatasetsFetched, isDatasourcesFetched]);
|
||||
|
||||
return {
|
||||
showWarning,
|
||||
hasDatasets: datasets?.length > 0,
|
||||
hasDatasources: datasources?.length > 0,
|
||||
isFetched: isDatasetsFetched && isDatasourcesFetched
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue